Merge branch 'release/v1.0.471'
This commit is contained in:
commit
bffa1bb2df
11 changed files with 277 additions and 213 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -1,6 +1,18 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
|
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
|
||||||
|
|
||||||
|
## [1.0.472] - 2024-10-03
|
||||||
|
### Added
|
||||||
|
- New `coffi.mem/null` var for implementing custom types
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- Upcall functions serialized from functions returned by deserializing function pointers now use the backing function pointer directly
|
||||||
|
- Upcall and downcall classes have been changed to be memoized, meaning ASM is no longer invoked every time a function is serialized, which should drastically improve performance where functions are serialized in a hot loop
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Incorrect docstring on `coffi.mem/address-of` that implied some type of pointer type was returned rather than a long
|
||||||
|
- Usage of deprecated `(Class/STATIC_FIELD)` access pattern
|
||||||
|
|
||||||
## [1.0.450] - 2024-10-02
|
## [1.0.450] - 2024-10-02
|
||||||
### Added
|
### Added
|
||||||
- Support for JDK 22
|
- Support for JDK 22
|
||||||
|
|
@ -133,6 +145,7 @@ All notable changes to this project will be documented in this file. This change
|
||||||
- Support for serializing and deserializing arbitrary Clojure functions
|
- Support for serializing and deserializing arbitrary Clojure functions
|
||||||
- Support for serializing and deserializing arbitrary Clojure data structures
|
- Support for serializing and deserializing arbitrary Clojure data structures
|
||||||
|
|
||||||
|
[1.0.472]: https://github.com/IGJoshua/coffi/compare/v1.0.450...v1.0.472
|
||||||
[1.0.450]: https://github.com/IGJoshua/coffi/compare/v0.6.409...v1.0.450
|
[1.0.450]: https://github.com/IGJoshua/coffi/compare/v0.6.409...v1.0.450
|
||||||
[0.6.409]: https://github.com/IGJoshua/coffi/compare/v0.5.357...v0.6.409
|
[0.6.409]: https://github.com/IGJoshua/coffi/compare/v0.5.357...v0.6.409
|
||||||
[0.5.357]: https://github.com/IGJoshua/coffi/compare/v0.4.341...v0.5.357
|
[0.5.357]: https://github.com/IGJoshua/coffi/compare/v0.4.341...v0.5.357
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ This library is available on Clojars. Add one of the following entries to the
|
||||||
`:deps` key of your `deps.edn`:
|
`:deps` key of your `deps.edn`:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
org.suskalo/coffi {:mvn/version "1.0.450"}
|
org.suskalo/coffi {:mvn/version "1.0.471"}
|
||||||
io.github.IGJoshua/coffi {:git/tag "v1.0.450" :git/sha "2676a7a"}
|
io.github.IGJoshua/coffi {:git/tag "v1.0.471" :git/sha "d3d2d25"}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use this library as a git dependency, you will need to prepare the
|
If you use this library as a git dependency, you will need to prepare the
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,7 @@
|
||||||
[clojure.tools.build.api :as b]))
|
[clojure.tools.build.api :as b]))
|
||||||
|
|
||||||
(def lib-coord 'org.suskalo/coffi)
|
(def lib-coord 'org.suskalo/coffi)
|
||||||
;;(def version (format "0.6.%s" (b/git-count-revs nil)))
|
(def version (format "1.0.%s" (b/git-count-revs nil)))
|
||||||
(def version "1.0.450")
|
|
||||||
|
|
||||||
(def resource-dirs ["resources/"])
|
(def resource-dirs ["resources/"])
|
||||||
|
|
||||||
|
|
|
||||||
9
deps.edn
9
deps.edn
|
|
@ -9,7 +9,8 @@
|
||||||
: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"}
|
||||||
nodisassemble/nodisassemble {:mvn/version "0.1.3"}}
|
nodisassemble/nodisassemble {:mvn/version "0.1.3"}
|
||||||
|
criterium/criterium {:mvn/version "0.4.6"}}
|
||||||
;; NOTE(Joshua): If you want to use nodisassemble you should also add a
|
;; NOTE(Joshua): If you want to use nodisassemble you should also add a
|
||||||
;; -javaagent for the resolved location
|
;; -javaagent for the resolved location
|
||||||
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]}
|
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]}
|
||||||
|
|
@ -21,11 +22,11 @@
|
||||||
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]
|
:jvm-opts ["--enable-native-access=ALL-UNNAMED"]
|
||||||
:exec-fn cognitect.test-runner.api/test}
|
:exec-fn cognitect.test-runner.api/test}
|
||||||
|
|
||||||
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
|
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}
|
||||||
:replace-deps {insn/insn {:mvn/version "0.2.1"}}
|
insn/insn {:mvn/version "0.2.1"}}
|
||||||
:exec-fn codox.main/generate-docs
|
:exec-fn codox.main/generate-docs
|
||||||
:exec-args {:name "coffi"
|
:exec-args {:name "coffi"
|
||||||
:version "v1.0.450"
|
:version "v1.0.471"
|
||||||
:description "A Foreign Function Interface in Clojure for JDK 22+."
|
:description "A Foreign Function Interface in Clojure for JDK 22+."
|
||||||
:source-paths ["src/clj"]
|
:source-paths ["src/clj"]
|
||||||
:output-path "docs"
|
:output-path "docs"
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,41 @@
|
||||||
<!DOCTYPE html PUBLIC ""
|
<!DOCTYPE html PUBLIC ""
|
||||||
"">
|
"">
|
||||||
<html><head><meta charset="UTF-8" /><title>coffi.ffi documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">coffi</span> <span class="project-version">v1.0.450</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>coffi</span></div></div></li><li class="depth-2 branch current"><a href="coffi.ffi.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ffi</span></div></a></li><li class="depth-2 branch"><a href="coffi.layout.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>layout</span></div></a></li><li class="depth-2"><a href="coffi.mem.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mem</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="coffi.ffi.html#var-cfn"><div class="inner"><span>cfn</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-const"><div class="inner"><span>const</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defcfn"><div class="inner"><span>defcfn</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defconst"><div class="inner"><span>defconst</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defvar"><div class="inner"><span>defvar</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-ensure-symbol"><div class="inner"><span>ensure-symbol</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-find-symbol"><div class="inner"><span>find-symbol</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-freset.21"><div class="inner"><span>freset!</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-fswap.21"><div class="inner"><span>fswap!</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-load-library"><div class="inner"><span>load-library</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-load-system-library"><div class="inner"><span>load-system-library</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-downcall"><div class="inner"><span>make-downcall</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-serde-varargs-wrapper"><div class="inner"><span>make-serde-varargs-wrapper</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-serde-wrapper"><div class="inner"><span>make-serde-wrapper</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-varargs-factory"><div class="inner"><span>make-varargs-factory</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-reify-libspec"><div class="inner"><span>reify-libspec</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-reify-symbolspec"><div class="inner"><span>reify-symbolspec</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-static-variable"><div class="inner"><span>static-variable</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-static-variable-segment"><div class="inner"><span>static-variable-segment</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-vacfn-factory"><div class="inner"><span>vacfn-factory</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">coffi.ffi</h1><div class="doc"><div class="markdown"><p>Functions for creating handles to native functions and loading native libraries.</p>
|
<html><head><meta charset="UTF-8" /><title>coffi.ffi documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">coffi</span> <span class="project-version">v1.0.471</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>coffi</span></div></div></li><li class="depth-2 branch current"><a href="coffi.ffi.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ffi</span></div></a></li><li class="depth-2 branch"><a href="coffi.layout.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>layout</span></div></a></li><li class="depth-2"><a href="coffi.mem.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mem</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="coffi.ffi.html#var-cfn"><div class="inner"><span>cfn</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-const"><div class="inner"><span>const</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defcfn"><div class="inner"><span>defcfn</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defconst"><div class="inner"><span>defconst</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-defvar"><div class="inner"><span>defvar</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-ensure-symbol"><div class="inner"><span>ensure-symbol</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-find-symbol"><div class="inner"><span>find-symbol</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-freset.21"><div class="inner"><span>freset!</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-fswap.21"><div class="inner"><span>fswap!</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-load-library"><div class="inner"><span>load-library</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-load-system-library"><div class="inner"><span>load-system-library</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-downcall"><div class="inner"><span>make-downcall</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-serde-varargs-wrapper"><div class="inner"><span>make-serde-varargs-wrapper</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-serde-wrapper"><div class="inner"><span>make-serde-wrapper</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-make-varargs-factory"><div class="inner"><span>make-varargs-factory</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-reify-libspec"><div class="inner"><span>reify-libspec</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-reify-symbolspec"><div class="inner"><span>reify-symbolspec</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-static-variable"><div class="inner"><span>static-variable</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-static-variable-segment"><div class="inner"><span>static-variable-segment</span></div></a></li><li class="depth-1"><a href="coffi.ffi.html#var-vacfn-factory"><div class="inner"><span>vacfn-factory</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">coffi.ffi</h1><div class="doc"><div class="markdown"><p>Functions for creating handles to native functions and loading native libraries.</p>
|
||||||
</div></div><div class="public anchor" id="var-cfn"><h3>cfn</h3><div class="usage"><code>(cfn symbol args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a Clojure function to call the native function referenced by <code>symbol</code>.</p>
|
</div></div><div class="public anchor" id="var-cfn"><h3>cfn</h3><div class="usage"><code>(cfn symbol args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a Clojure function to call the native function referenced by <code>symbol</code>.</p>
|
||||||
<p>The function returned will serialize any passed arguments into the <code>args</code> types, and deserialize the return to the <code>ret</code> type.</p>
|
<p>The function returned will serialize any passed arguments into the <code>args</code> types, and deserialize the return to the <code>ret</code> type.</p>
|
||||||
<p>If your <code>args</code> and <code>ret</code> are constants, then it is more efficient to call <a href="coffi.ffi.html#var-make-downcall">make-downcall</a> followed by <a href="coffi.ffi.html#var-make-serde-wrapper">make-serde-wrapper</a> because the latter has an inline definition which will result in less overhead from serdes.</p>
|
<p>If your <code>args</code> and <code>ret</code> are constants, then it is more efficient to call <a href="coffi.ffi.html#var-make-downcall">make-downcall</a> followed by <a href="coffi.ffi.html#var-make-serde-wrapper">make-serde-wrapper</a> because the latter has an inline definition which will result in less overhead from serdes.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L421">view source</a></div></div><div class="public anchor" id="var-const"><h3>const</h3><div class="usage"><code>(const symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Gets the value of a constant stored in <code>symbol-or-addr</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L438">view source</a></div></div><div class="public anchor" id="var-const"><h3>const</h3><div class="usage"><code>(const symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Gets the value of a constant stored in <code>symbol-or-addr</code>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L564">view source</a></div></div><div class="public anchor" id="var-defcfn"><h3>defcfn</h3><h4 class="type">macro</h4><div class="usage"><code>(defcfn name docstring? attr-map? symbol arg-types ret-type)</code><code>(defcfn name docstring? attr-map? symbol arg-types ret-type native-fn & fn-tail)</code></div><div class="doc"><div class="markdown"><p>Defines a Clojure function which maps to a native function.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L606">view source</a></div></div><div class="public anchor" id="var-defcfn"><h3>defcfn</h3><h4 class="type">macro</h4><div class="usage"><code>(defcfn name docstring? attr-map? symbol arg-types ret-type)</code><code>(defcfn name docstring? attr-map? symbol arg-types ret-type native-fn & fn-tail)</code></div><div class="doc"><div class="markdown"><p>Defines a Clojure function which maps to a native function.</p>
|
||||||
<p><code>name</code> is the symbol naming the resulting var. <code>symbol</code> is a symbol or string naming the library symbol to link against. <code>arg-types</code> is a vector of qualified keywords representing the argument types. <code>ret-type</code> is a single qualified keyword representing the return type. <code>fn-tail</code> is the body of the function (potentially with multiple arities) which wraps the native one. Inside the function, <code>native-fn</code> is bound to a function that will serialize its arguments, call the native function, and deserialize its return type. If any body is present, you must call this function in order to call the native code.</p>
|
<p><code>name</code> is the symbol naming the resulting var. <code>symbol</code> is a symbol or string naming the library symbol to link against. <code>arg-types</code> is a vector of qualified keywords representing the argument types. <code>ret-type</code> is a single qualified keyword representing the return type. <code>fn-tail</code> is the body of the function (potentially with multiple arities) which wraps the native one. Inside the function, <code>native-fn</code> is bound to a function that will serialize its arguments, call the native function, and deserialize its return type. If any body is present, you must call this function in order to call the native code.</p>
|
||||||
<p>If no <code>fn-tail</code> is provided, then the resulting function will simply serialize the arguments according to <code>arg-types</code>, call the native function, and deserialize the return value.</p>
|
<p>If no <code>fn-tail</code> is provided, then the resulting function will simply serialize the arguments according to <code>arg-types</code>, call the native function, and deserialize the return value.</p>
|
||||||
<p>The number of args in the <code>fn-tail</code> need not match the number of <code>arg-types</code> for the native function. It need only call the native wrapper function with the correct arguments.</p>
|
<p>The number of args in the <code>fn-tail</code> need not match the number of <code>arg-types</code> for the native function. It need only call the native wrapper function with the correct arguments.</p>
|
||||||
<p>See <a href="coffi.mem.html#var-serialize">serialize</a>, <a href="coffi.mem.html#var-deserialize">deserialize</a>, <a href="coffi.ffi.html#var-make-downcall">make-downcall</a>.</p>
|
<p>See <a href="coffi.mem.html#var-serialize">serialize</a>, <a href="coffi.mem.html#var-deserialize">deserialize</a>, <a href="coffi.ffi.html#var-make-downcall">make-downcall</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L738">view source</a></div></div><div class="public anchor" id="var-defconst"><h3>defconst</h3><h4 class="type">macro</h4><div class="usage"><code>(defconst symbol docstring? symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Defines a var named by <code>symbol</code> to be the value of the given <code>type</code> from <code>symbol-or-addr</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L780">view source</a></div></div><div class="public anchor" id="var-defconst"><h3>defconst</h3><h4 class="type">macro</h4><div class="usage"><code>(defconst symbol docstring? symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Defines a var named by <code>symbol</code> to be the value of the given <code>type</code> from <code>symbol-or-addr</code>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L575">view source</a></div></div><div class="public anchor" id="var-defvar"><h3>defvar</h3><h4 class="type">macro</h4><div class="usage"><code>(defvar symbol docstring? symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Defines a var named by <code>symbol</code> to be a reference to the native memory from <code>symbol-or-addr</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L617">view source</a></div></div><div class="public anchor" id="var-defvar"><h3>defvar</h3><h4 class="type">macro</h4><div class="usage"><code>(defvar symbol docstring? symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Defines a var named by <code>symbol</code> to be a reference to the native memory from <code>symbol-or-addr</code>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L641">view source</a></div></div><div class="public anchor" id="var-ensure-symbol"><h3>ensure-symbol</h3><div class="usage"><code>(ensure-symbol symbol-or-addr)</code></div><div class="doc"><div class="markdown"><p>Returns the argument if it is a <a href="null">MemorySegment</a>, otherwise calls <a href="coffi.ffi.html#var-find-symbol">find-symbol</a> on it.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L683">view source</a></div></div><div class="public anchor" id="var-ensure-symbol"><h3>ensure-symbol</h3><div class="usage"><code>(ensure-symbol symbol-or-addr)</code></div><div class="doc"><div class="markdown"><p>Returns the argument if it is a <a href="null">MemorySegment</a>, otherwise calls <a href="coffi.ffi.html#var-find-symbol">find-symbol</a> on it.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L181">view source</a></div></div><div class="public anchor" id="var-find-symbol"><h3>find-symbol</h3><div class="usage"><code>(find-symbol sym)</code></div><div class="doc"><div class="markdown"><p>Gets the <a href="null">MemorySegment</a> of a symbol from the loaded libraries.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L198">view source</a></div></div><div class="public anchor" id="var-find-symbol"><h3>find-symbol</h3><div class="usage"><code>(find-symbol sym)</code></div><div class="doc"><div class="markdown"><p>Gets the <a href="null">MemorySegment</a> of a symbol from the loaded libraries.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L38">view source</a></div></div><div class="public anchor" id="var-freset.21"><h3>freset!</h3><div class="usage"><code>(freset! static-var newval)</code></div><div class="doc"><div class="markdown"><p>Sets the value of <code>static-var</code> to <code>newval</code>, running it through <a href="coffi.mem.html#var-serialize">serialize</a>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L38">view source</a></div></div><div class="public anchor" id="var-freset.21"><h3>freset!</h3><div class="usage"><code>(freset! static-var newval)</code></div><div class="doc"><div class="markdown"><p>Sets the value of <code>static-var</code> to <code>newval</code>, running it through <a href="coffi.mem.html#var-serialize">serialize</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L605">view source</a></div></div><div class="public anchor" id="var-fswap.21"><h3>fswap!</h3><div class="usage"><code>(fswap! static-var f & args)</code></div><div class="doc"><div class="markdown"><p>Non-atomically runs the function <code>f</code> over the value stored in <code>static-var</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L647">view source</a></div></div><div class="public anchor" id="var-fswap.21"><h3>fswap!</h3><div class="usage"><code>(fswap! static-var f & args)</code></div><div class="doc"><div class="markdown"><p>Non-atomically runs the function <code>f</code> over the value stored in <code>static-var</code>.</p>
|
||||||
<p>The value is deserialized before passing it to <code>f</code>, and serialized before putting the value into <code>static-var</code>.</p>
|
<p>The value is deserialized before passing it to <code>f</code>, and serialized before putting the value into <code>static-var</code>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L614">view source</a></div></div><div class="public anchor" id="var-load-library"><h3>load-library</h3><div class="usage"><code>(load-library path)</code></div><div class="doc"><div class="markdown"><p>Loads the library at <code>path</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L656">view source</a></div></div><div class="public anchor" id="var-load-library"><h3>load-library</h3><div class="usage"><code>(load-library path)</code></div><div class="doc"><div class="markdown"><p>Loads the library at <code>path</code>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L33">view source</a></div></div><div class="public anchor" id="var-load-system-library"><h3>load-system-library</h3><div class="usage"><code>(load-system-library libname)</code></div><div class="doc"><div class="markdown"><p>Loads the library named <code>libname</code> from the system’s load path.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L33">view source</a></div></div><div class="public anchor" id="var-load-system-library"><h3>load-system-library</h3><div class="usage"><code>(load-system-library libname)</code></div><div class="doc"><div class="markdown"><p>Loads the library named <code>libname</code> from the system’s load path.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L28">view source</a></div></div><div class="public anchor" id="var-make-downcall"><h3>make-downcall</h3><div class="usage"><code>(make-downcall symbol-or-addr args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a downcall function reference to <code>symbol-or-addr</code> with the given <code>args</code> and <code>ret</code> types.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L28">view source</a></div></div><div class="public anchor" id="var-make-downcall"><h3>make-downcall</h3><div class="usage"><code>(make-downcall symbol-or-addr args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a downcall function reference to <code>symbol-or-addr</code> with the given <code>args</code> and <code>ret</code> types.</p>
|
||||||
<p>The function returned takes only arguments whose types match exactly the <a href="coffi.mem.html#var-java-layout">java-layout</a> for that type, and returns an argument with exactly the <a href="coffi.mem.html#var-java-layout">java-layout</a> of the <code>ret</code> type. This function will perform no serialization or deserialization of arguments or the return type.</p>
|
<p>The function returned takes only arguments whose types match exactly the <a href="coffi.mem.html#var-java-layout">java-layout</a> for that type, and returns an argument with exactly the <a href="coffi.mem.html#var-java-layout">java-layout</a> of the <code>ret</code> type. This function will perform no serialization or deserialization of arguments or the return type.</p>
|
||||||
<p>If the <code>ret</code> type is non-primitive, then the returned function will take a first argument of a <a href="null">SegmentAllocator</a>.</p>
|
<p>If the <code>ret</code> type is non-primitive, then the returned function will take a first argument of a <a href="null">SegmentAllocator</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L189">view source</a></div></div><div class="public anchor" id="var-make-serde-varargs-wrapper"><h3>make-serde-varargs-wrapper</h3><div class="usage"><code>(make-serde-varargs-wrapper varargs-factory required-args ret-type)</code></div><div class="doc"><div class="markdown"><p>Constructs a wrapper function for the <code>varargs-factory</code> which produces functions that serialize the arguments and deserialize the return value.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L206">view source</a></div></div><div class="public anchor" id="var-make-serde-varargs-wrapper"><h3>make-serde-varargs-wrapper</h3><div class="usage"><code>(make-serde-varargs-wrapper varargs-factory required-args ret-type)</code></div><div class="doc"><div class="markdown"><p>Constructs a wrapper function for the <code>varargs-factory</code> which produces functions that serialize the arguments and deserialize the return value.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L409">view source</a></div></div><div class="public anchor" id="var-make-serde-wrapper"><h3>make-serde-wrapper</h3><div class="usage"><code>(make-serde-wrapper downcall arg-types ret-type)</code></div><div class="doc"><div class="markdown"><p>Constructs a wrapper function for the <code>downcall</code> which serializes the arguments and deserializes the return value.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L426">view source</a></div></div><div class="public anchor" id="var-make-serde-wrapper"><h3>make-serde-wrapper</h3><div class="usage"><code>(make-serde-wrapper downcall arg-types ret-type)</code></div><div class="doc"><div class="markdown"><p>Constructs a wrapper function for the <code>downcall</code> which serializes the arguments and deserializes the return value.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L390">view source</a></div></div><div class="public anchor" id="var-make-varargs-factory"><h3>make-varargs-factory</h3><div class="usage"><code>(make-varargs-factory symbol required-args ret)</code></div><div class="doc"><div class="markdown"><p>Returns a function for constructing downcalls with additional types for arguments.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L407">view source</a></div></div><div class="public anchor" id="var-make-varargs-factory"><h3>make-varargs-factory</h3><div class="usage"><code>(make-varargs-factory symbol required-args ret)</code></div><div class="doc"><div class="markdown"><p>Returns a function for constructing downcalls with additional types for arguments.</p>
|
||||||
<p>The <code>required-args</code> are the types of the first arguments passed to the downcall handle, and the values passed to the returned function are only the varargs types.</p>
|
<p>The <code>required-args</code> are the types of the first arguments passed to the downcall handle, and the values passed to the returned function are only the varargs types.</p>
|
||||||
<p>The returned function is memoized, so that only one downcall function will be generated per combination of argument types.</p>
|
<p>The returned function is memoized, so that only one downcall function will be generated per combination of argument types.</p>
|
||||||
<p>See <a href="coffi.ffi.html#var-make-downcall">make-downcall</a>.</p>
|
<p>See <a href="coffi.ffi.html#var-make-downcall">make-downcall</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L205">view source</a></div></div><div class="public anchor" id="var-reify-libspec"><h3>reify-libspec</h3><div class="usage"><code>(reify-libspec libspec)</code></div><div class="doc"><div class="markdown"><p>Loads all the symbols specified in the <code>libspec</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L222">view source</a></div></div><div class="public anchor" id="var-reify-libspec"><h3>reify-libspec</h3><div class="usage"><code>(reify-libspec libspec)</code></div><div class="doc"><div class="markdown"><p>Loads all the symbols specified in the <code>libspec</code>.</p>
|
||||||
<p>The value of each key of the passed map is transformed as by <a href="coffi.ffi.html#var-reify-symbolspec">reify-symbolspec</a>.</p>
|
<p>The value of each key of the passed map is transformed as by <a href="coffi.ffi.html#var-reify-symbolspec">reify-symbolspec</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L700">view source</a></div></div><div class="public anchor" id="var-reify-symbolspec"><h3>reify-symbolspec</h3><h4 class="type">multimethod</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>Takes a spec for a symbol reference and returns a live value for that type.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L742">view source</a></div></div><div class="public anchor" id="var-reify-symbolspec"><h3>reify-symbolspec</h3><h4 class="type">multimethod</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>Takes a spec for a symbol reference and returns a live value for that type.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L659">view source</a></div></div><div class="public anchor" id="var-static-variable"><h3>static-variable</h3><div class="usage"><code>(static-variable symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Constructs a reference to a mutable value stored in <code>symbol-or-addr</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L701">view source</a></div></div><div class="public anchor" id="var-static-variable"><h3>static-variable</h3><div class="usage"><code>(static-variable symbol-or-addr type)</code></div><div class="doc"><div class="markdown"><p>Constructs a reference to a mutable value stored in <code>symbol-or-addr</code>.</p>
|
||||||
<p>The returned value can be dereferenced, and has metadata.</p>
|
<p>The returned value can be dereferenced, and has metadata.</p>
|
||||||
<p>See <a href="coffi.ffi.html#var-freset.21">freset!</a>, <a href="coffi.ffi.html#var-fswap.21">fswap!</a>.</p>
|
<p>See <a href="coffi.ffi.html#var-freset.21">freset!</a>, <a href="coffi.ffi.html#var-fswap.21">fswap!</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L630">view source</a></div></div><div class="public anchor" id="var-static-variable-segment"><h3>static-variable-segment</h3><div class="usage"><code>(static-variable-segment static-var)</code></div><div class="doc"><div class="markdown"><p>Gets the backing <a href="null">MemorySegment</a> from <code>static-var</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L672">view source</a></div></div><div class="public anchor" id="var-static-variable-segment"><h3>static-variable-segment</h3><div class="usage"><code>(static-variable-segment static-var)</code></div><div class="doc"><div class="markdown"><p>Gets the backing <a href="null">MemorySegment</a> from <code>static-var</code>.</p>
|
||||||
<p>This is primarily useful when you need to pass the static variable’s address to a native function which takes an <a href="null">Addressable</a>.</p>
|
<p>This is primarily useful when you need to pass the static variable’s address to a native function which takes an <a href="null">Addressable</a>.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L622">view source</a></div></div><div class="public anchor" id="var-vacfn-factory"><h3>vacfn-factory</h3><div class="usage"><code>(vacfn-factory symbol required-args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a varargs factory to call the native function referenced by <code>symbol</code>.</p>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L664">view source</a></div></div><div class="public anchor" id="var-vacfn-factory"><h3>vacfn-factory</h3><div class="usage"><code>(vacfn-factory symbol required-args ret)</code></div><div class="doc"><div class="markdown"><p>Constructs a varargs factory to call the native function referenced by <code>symbol</code>.</p>
|
||||||
<p>The function returned takes any number of type arguments and returns a specialized Clojure function for calling the native function with those arguments.</p>
|
<p>The function returned takes any number of type arguments and returns a specialized Clojure function for calling the native function with those arguments.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/ffi.clj#L436">view source</a></div></div></div></body></html>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/ffi.clj#L453">view source</a></div></div></div></body></html>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html PUBLIC ""
|
<!DOCTYPE html PUBLIC ""
|
||||||
"">
|
"">
|
||||||
<html><head><meta charset="UTF-8" /><title>coffi.layout documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">coffi</span> <span class="project-version">v1.0.450</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>coffi</span></div></div></li><li class="depth-2 branch"><a href="coffi.ffi.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ffi</span></div></a></li><li class="depth-2 branch current"><a href="coffi.layout.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>layout</span></div></a></li><li class="depth-2"><a href="coffi.mem.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mem</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="coffi.layout.html#var-with-c-layout"><div class="inner"><span>with-c-layout</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">coffi.layout</h1><div class="doc"><div class="markdown"><p>Functions for adjusting the layout of structs.</p>
|
<html><head><meta charset="UTF-8" /><title>coffi.layout documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">coffi</span> <span class="project-version">v1.0.471</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>coffi</span></div></div></li><li class="depth-2 branch"><a href="coffi.ffi.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ffi</span></div></a></li><li class="depth-2 branch current"><a href="coffi.layout.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>layout</span></div></a></li><li class="depth-2"><a href="coffi.mem.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mem</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="coffi.layout.html#var-with-c-layout"><div class="inner"><span>with-c-layout</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">coffi.layout</h1><div class="doc"><div class="markdown"><p>Functions for adjusting the layout of structs.</p>
|
||||||
</div></div><div class="public anchor" id="var-with-c-layout"><h3>with-c-layout</h3><div class="usage"><code>(with-c-layout struct-spec)</code></div><div class="doc"><div class="markdown"><p>Forces a struct specification to C layout rules.</p>
|
</div></div><div class="public anchor" id="var-with-c-layout"><h3>with-c-layout</h3><div class="usage"><code>(with-c-layout struct-spec)</code></div><div class="doc"><div class="markdown"><p>Forces a struct specification to C layout rules.</p>
|
||||||
<p>This will add padding fields between fields to match C alignment requirements.</p>
|
<p>This will add padding fields between fields to match C alignment requirements.</p>
|
||||||
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/bcf2e031f995d1c7473797c70f94b9731634c97b/src/clj/coffi/layout.clj#L6">view source</a></div></div></div></body></html>
|
</div></div><div class="src-link"><a href="https://github.com/IGJoshua/coffi/blob/d3d2d25c782aed60672c80b1494337c91151783a/src/clj/coffi/layout.clj#L6">view source</a></div></div></div></body></html>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -130,10 +130,13 @@
|
||||||
[:invokevirtual (prim-classes prim-type) (unbox-fn-for-type prim-type) [prim]]]
|
[:invokevirtual (prim-classes prim-type) (unbox-fn-for-type prim-type) [prim]]]
|
||||||
[]))))
|
[]))))
|
||||||
|
|
||||||
(defn- downcall-class
|
(defn- downcall-class-ctor*
|
||||||
"Class definition for an implementation of [[IFn]] which calls a closed over
|
"Returns a function to construct a downcall class for the given `args` and `ret` types.
|
||||||
|
|
||||||
|
A downcall class is an implementation of [[IFn]] which calls a closed over
|
||||||
method handle without reflection, unboxing primitives when needed."
|
method handle without reflection, unboxing primitives when needed."
|
||||||
[args ret]
|
[args ret]
|
||||||
|
(let [klass (insn/define
|
||||||
{:flags #{:public :final}
|
{:flags #{:public :final}
|
||||||
:version 8
|
:version 8
|
||||||
:super clojure.lang.AFunction
|
:super clojure.lang.AFunction
|
||||||
|
|
@ -172,11 +175,25 @@
|
||||||
(not (mem/primitive-type ret)) (cons SegmentAllocator))]
|
(not (mem/primitive-type ret)) (cons SegmentAllocator))]
|
||||||
(to-object-asm ret)
|
(to-object-asm ret)
|
||||||
[:areturn]]}]})
|
[:areturn]]}]})
|
||||||
|
ctor (.getConstructor klass
|
||||||
|
(doto ^"[Ljava.lang.Class;" (make-array Class 1)
|
||||||
|
(aset 0 MethodHandle)))]
|
||||||
|
(fn [^MethodHandle h]
|
||||||
|
(.newInstance ctor
|
||||||
|
(doto (object-array 1)
|
||||||
|
(aset 0 h))))))
|
||||||
|
|
||||||
|
(def ^:private downcall-class-ctor
|
||||||
|
"Returns a function to construct a downcall class for the given memoized `args` and `ret` types.
|
||||||
|
|
||||||
|
A downcall class is an implementation of [[IFn]] which calls a closed over
|
||||||
|
method handle without reflection, unboxing primitives when needed."
|
||||||
|
(memoize downcall-class-ctor*))
|
||||||
|
|
||||||
(defn- downcall-fn
|
(defn- downcall-fn
|
||||||
"Creates a function to call `handle` without reflection."
|
"Creates a function to call `handle` without reflection."
|
||||||
[handle args ret]
|
[handle args ret]
|
||||||
(insn/new-instance (downcall-class args ret) ^MethodHandle handle))
|
((downcall-class-ctor args ret) ^MethodHandle handle))
|
||||||
|
|
||||||
(defn ensure-symbol
|
(defn ensure-symbol
|
||||||
"Returns the argument if it is a [[MemorySegment]], otherwise
|
"Returns the argument if it is a [[MemorySegment]], otherwise
|
||||||
|
|
@ -292,7 +309,7 @@
|
||||||
|
|
||||||
;; cast null pointers to something understood by panama
|
;; cast null pointers to something understood by panama
|
||||||
(#{::mem/pointer} type)
|
(#{::mem/pointer} type)
|
||||||
`(or ~sym (MemorySegment/NULL))
|
`(or ~sym mem/null)
|
||||||
|
|
||||||
(mem/primitive-type type)
|
(mem/primitive-type type)
|
||||||
`(mem/serialize* ~sym ~type-sym ~arena)
|
`(mem/serialize* ~sym ~type-sym ~arena)
|
||||||
|
|
@ -462,10 +479,13 @@
|
||||||
"Set of primitive types which require 2 indices in the constant pool."
|
"Set of primitive types which require 2 indices in the constant pool."
|
||||||
#{::mem/double ::mem/long})
|
#{::mem/double ::mem/long})
|
||||||
|
|
||||||
(defn- upcall-class
|
(defn- upcall-class-ctor*
|
||||||
"Constructs a class definition for a class with a single method, `upcall`, which
|
"Returns a function to construct an upcall class for the given `arg-types` and `ret-types`.
|
||||||
boxes any primitives passed to it and calls a closed over [[IFn]]."
|
|
||||||
|
An upcall class is a class with a single method, `upcall`, which boxes any
|
||||||
|
primitives passed to it and calls a closed over [[IFn]]."
|
||||||
[arg-types ret-type]
|
[arg-types ret-type]
|
||||||
|
(let [klass (insn/define
|
||||||
{:flags #{:public :final}
|
{:flags #{:public :final}
|
||||||
:version 8
|
:version 8
|
||||||
:fields [{:name "upcall_ifn"
|
:fields [{:name "upcall_ifn"
|
||||||
|
|
@ -501,11 +521,27 @@
|
||||||
[:invokeinterface IFn "invoke" (repeat (inc (count arg-types)) Object)]
|
[:invokeinterface IFn "invoke" (repeat (inc (count arg-types)) Object)]
|
||||||
(to-prim-asm ret-type)
|
(to-prim-asm ret-type)
|
||||||
[(return-for-type ret-type :areturn)]]}]})
|
[(return-for-type ret-type :areturn)]]}]})
|
||||||
|
ctor (.getConstructor klass
|
||||||
|
(doto ^"[Ljava.lang.Class;" (make-array Class 1)
|
||||||
|
(aset 0 IFn)))]
|
||||||
|
(fn [^IFn f]
|
||||||
|
(.newInstance ctor
|
||||||
|
(doto (object-array 1)
|
||||||
|
(aset 0 f))))))
|
||||||
|
|
||||||
|
(def ^:private upcall-class-ctor
|
||||||
|
"Returns a function to construct an upcall class for the given memoized `arg-types` and `ret-types`.
|
||||||
|
|
||||||
|
An upcall class is a class with a single method, `upcall`, which boxes any
|
||||||
|
primitives passed to it and calls a closed over [[IFn]]."
|
||||||
|
(memoize upcall-class-ctor*))
|
||||||
|
|
||||||
(defn- upcall
|
(defn- upcall
|
||||||
"Constructs an instance of [[upcall-class]], closing over `f`."
|
"Constructs an instance of an upcall class, closing over `f`.
|
||||||
|
|
||||||
|
See [[upcall-class-ctor]]."
|
||||||
[f arg-types ret-type]
|
[f arg-types ret-type]
|
||||||
(insn/new-instance (upcall-class arg-types ret-type) ^IFn f))
|
((upcall-class-ctor arg-types ret-type) ^IFn f))
|
||||||
|
|
||||||
(defn- method-type
|
(defn- method-type
|
||||||
"Gets the [[MethodType]] for a set of `args` and `ret` types."
|
"Gets the [[MethodType]] for a set of `args` and `ret` types."
|
||||||
|
|
@ -539,7 +575,11 @@
|
||||||
(mem/global-arena))))
|
(mem/global-arena))))
|
||||||
|
|
||||||
(defmethod mem/serialize* ::fn
|
(defmethod mem/serialize* ::fn
|
||||||
[f [_fn arg-types ret-type & {:keys [raw-fn?]}] arena]
|
[f [_fn arg-types ret-type & {:keys [raw-fn?]} :as typ] arena]
|
||||||
|
(if-let [address (::address (meta f))]
|
||||||
|
(do (assert (= typ (::type (meta f)))
|
||||||
|
"The type of a deserialized function must match the type it is re-serialized to.")
|
||||||
|
address)
|
||||||
(.upcallStub
|
(.upcallStub
|
||||||
(Linker/nativeLinker)
|
(Linker/nativeLinker)
|
||||||
^MethodHandle (cond-> f
|
^MethodHandle (cond-> f
|
||||||
|
|
@ -547,17 +587,19 @@
|
||||||
:always (upcall-handle arg-types ret-type))
|
:always (upcall-handle arg-types ret-type))
|
||||||
^FunctionDescriptor (function-descriptor arg-types ret-type)
|
^FunctionDescriptor (function-descriptor arg-types ret-type)
|
||||||
^Arena arena
|
^Arena arena
|
||||||
(make-array Linker$Option 0)))
|
(make-array Linker$Option 0))))
|
||||||
|
|
||||||
(defmethod mem/deserialize* ::fn
|
(defmethod mem/deserialize* ::fn
|
||||||
[addr [_fn arg-types ret-type & {:keys [raw-fn?]}]]
|
[addr [_fn arg-types ret-type & {:keys [raw-fn?] :as typ}]]
|
||||||
(when-not (mem/null? addr)
|
(when-not (mem/null? addr)
|
||||||
(vary-meta
|
(vary-meta
|
||||||
(-> ^MemorySegment addr
|
(-> ^MemorySegment addr
|
||||||
(downcall-handle (function-descriptor arg-types ret-type))
|
(downcall-handle (function-descriptor arg-types ret-type))
|
||||||
(downcall-fn arg-types ret-type)
|
(downcall-fn arg-types ret-type)
|
||||||
(cond-> (not raw-fn?) (make-serde-wrapper arg-types ret-type)))
|
(cond-> (not raw-fn?) (make-serde-wrapper arg-types ret-type)))
|
||||||
assoc ::address addr)))
|
assoc
|
||||||
|
::address addr
|
||||||
|
::type typ)))
|
||||||
|
|
||||||
;;; Static memory access
|
;;; Static memory access
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,16 +106,22 @@
|
||||||
(.allocate ^SegmentAllocator allocator (long size) (long alignment))))
|
(.allocate ^SegmentAllocator allocator (long size) (long alignment))))
|
||||||
|
|
||||||
(defn address-of
|
(defn address-of
|
||||||
"Gets the address of a given segment.
|
"Gets the address of a given segment as a number."
|
||||||
|
|
||||||
This value can be used as an argument to functions which take a pointer."
|
|
||||||
^long [addressable]
|
^long [addressable]
|
||||||
(.address ^MemorySegment addressable))
|
(.address ^MemorySegment addressable))
|
||||||
|
|
||||||
|
(def ^MemorySegment null
|
||||||
|
"The NULL pointer object.
|
||||||
|
|
||||||
|
While this object is safe to pass to functions which serialize to a pointer,
|
||||||
|
it's generally encouraged to simply pass `nil`. This value primarily exists to
|
||||||
|
make it easier to write custom types with a primitive pointer representation."
|
||||||
|
MemorySegment/NULL)
|
||||||
|
|
||||||
(defn null?
|
(defn null?
|
||||||
"Checks if a memory address is null."
|
"Checks if a memory address is null."
|
||||||
[addr]
|
[addr]
|
||||||
(or (.equals (MemorySegment/NULL) addr) (not addr)))
|
(or (.equals null addr) (not addr)))
|
||||||
|
|
||||||
(defn address?
|
(defn address?
|
||||||
"Checks if an object is a memory address.
|
"Checks if an object is a memory address.
|
||||||
|
|
@ -872,7 +878,7 @@
|
||||||
(serialize-into obj (second type) segment arena)
|
(serialize-into obj (second type) segment arena)
|
||||||
(address-of segment))
|
(address-of segment))
|
||||||
obj)
|
obj)
|
||||||
(MemorySegment/NULL)))
|
null))
|
||||||
|
|
||||||
(defmethod serialize* ::void
|
(defmethod serialize* ::void
|
||||||
[_obj _type _arena]
|
[_obj _type _arena]
|
||||||
|
|
@ -1132,7 +1138,7 @@
|
||||||
[obj _type ^Arena arena]
|
[obj _type ^Arena arena]
|
||||||
(if obj
|
(if obj
|
||||||
(.allocateFrom arena ^String obj)
|
(.allocateFrom arena ^String obj)
|
||||||
(MemorySegment/NULL)))
|
null))
|
||||||
|
|
||||||
(defmethod deserialize* ::c-string
|
(defmethod deserialize* ::c-string
|
||||||
[addr _type]
|
[addr _type]
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,11 @@
|
||||||
|
|
||||||
(t/deftest can-call-with-trailing-string-arg
|
(t/deftest can-call-with-trailing-string-arg
|
||||||
(t/is
|
(t/is
|
||||||
(=
|
(= (try ((ffi/cfn "test_call_with_trailing_string_arg"
|
||||||
((ffi/cfn "test_call_with_trailing_string_arg"
|
|
||||||
[::mem/int ::mem/int ::mem/c-string]
|
[::mem/int ::mem/int ::mem/c-string]
|
||||||
::mem/void)
|
::mem/void)
|
||||||
1 2 "third arg"))))
|
1 2 "third arg")
|
||||||
|
:ok
|
||||||
|
(catch Throwable _t
|
||||||
|
:err))
|
||||||
|
:ok)))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue