Add macros to ease creating static variable references
This commit is contained in:
parent
20956f2549
commit
d7e0ced38b
3 changed files with 43 additions and 3 deletions
|
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This change
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- New macros for defining vars with values from native code
|
||||||
- New function to allow getting the backing memory segment of a `coffi.ffi.StaticVariable`, to replace the `Addressable` implementation lost in the migration to JDK 18
|
- New function to allow getting the backing memory segment of a `coffi.ffi.StaticVariable`, to replace the `Addressable` implementation lost in the migration to JDK 18
|
||||||
|
|
||||||
## [0.5.357] - 2022-07-07
|
## [0.5.357] - 2022-07-07
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -265,18 +265,21 @@ does not support va-list, however it is a planned feature.
|
||||||
|
|
||||||
### Global Variables
|
### Global Variables
|
||||||
Some libraries include global variables or constants accessible through symbols.
|
Some libraries include global variables or constants accessible through symbols.
|
||||||
To start with, constant values stored in symbols can be fetched with `const`
|
To start with, constant values stored in symbols can be fetched with `const`, or
|
||||||
|
the parallel macro `defconst`
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(def some-const (ffi/const "some_const" ::mem/int))
|
(def some-const (ffi/const "some_const" ::mem/int))
|
||||||
|
(ffi/defconst some-const "some_const" ::mem/int)
|
||||||
```
|
```
|
||||||
|
|
||||||
This value is fetched once when you call `const` and is turned into a Clojure
|
This value is fetched once when you call `const` and is turned into a Clojure
|
||||||
value. If you need to refer to a global variable, then `static-variable` can be
|
value. If you need to refer to a global variable, then `static-variable` (or
|
||||||
used to create a reference to the native value.
|
parallel `defvar`) can be used to create a reference to the native value.
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(def some-var (ffi/static-variable "some_var" ::mem/int))
|
(def some-var (ffi/static-variable "some_var" ::mem/int))
|
||||||
|
(ffi/defvar some-var "some_var" ::mem/int)
|
||||||
```
|
```
|
||||||
|
|
||||||
This variable is an `IDeref`. Each time you dereference it, the value will be
|
This variable is an `IDeref`. Each time you dereference it, the value will be
|
||||||
|
|
@ -297,6 +300,10 @@ value is being mutated on another thread.
|
||||||
A parallel function `fswap!` is also provided, but it does not provide any
|
A parallel function `fswap!` is also provided, but it does not provide any
|
||||||
atomic semantics either.
|
atomic semantics either.
|
||||||
|
|
||||||
|
The memory that backs the static variable can be fetched with the function
|
||||||
|
`static-variable-segment`, which can be used to pass a pointer to the static
|
||||||
|
variable to native functions that require it.
|
||||||
|
|
||||||
### Complex Wrappers
|
### Complex Wrappers
|
||||||
Some functions require more complex code to map nicely to a Clojure function.
|
Some functions require more complex code to map nicely to a Clojure function.
|
||||||
The `defcfn` macro provides facilities to wrap the native function with some
|
The `defcfn` macro provides facilities to wrap the native function with some
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,25 @@
|
||||||
[symbol-or-addr type]
|
[symbol-or-addr type]
|
||||||
(mem/deserialize (.address (ensure-symbol symbol-or-addr)) [::mem/pointer type]))
|
(mem/deserialize (.address (ensure-symbol symbol-or-addr)) [::mem/pointer type]))
|
||||||
|
|
||||||
|
(s/def ::defconst-args
|
||||||
|
(s/cat :var-name simple-symbol?
|
||||||
|
:docstring (s/? string?)
|
||||||
|
:symbol-or-addr any?
|
||||||
|
:type ::mem/type))
|
||||||
|
|
||||||
|
(defmacro defconst
|
||||||
|
"Defines a var named by `symbol` to be the value of the given `type` from `symbol-or-addr`."
|
||||||
|
{:arglists '([symbol docstring? symbol-or-addr type])}
|
||||||
|
[& args]
|
||||||
|
(let [args (s/conform ::defconst-args args)]
|
||||||
|
`(let [symbol# (ensure-symbol ~(:symbol-or-addr args))]
|
||||||
|
(def ~(:var-name args)
|
||||||
|
~@(when-let [doc (:docstring args)]
|
||||||
|
(list doc))
|
||||||
|
(const symbol# ~(:type args))))))
|
||||||
|
(s/fdef defconst
|
||||||
|
:args ::defconst-args)
|
||||||
|
|
||||||
(deftype StaticVariable [seg type meta]
|
(deftype StaticVariable [seg type meta]
|
||||||
IDeref
|
IDeref
|
||||||
(deref [_]
|
(deref [_]
|
||||||
|
|
@ -615,6 +634,19 @@
|
||||||
(mem/global-scope))
|
(mem/global-scope))
|
||||||
type (atom nil)))
|
type (atom nil)))
|
||||||
|
|
||||||
|
(defmacro defvar
|
||||||
|
"Defines a var named by `symbol` to be a reference to the native memory from `symbol-or-addr`."
|
||||||
|
{:arglists '([symbol docstring? symbol-or-addr type])}
|
||||||
|
[& args]
|
||||||
|
(let [args (s/conform ::defconst-args args)]
|
||||||
|
`(let [symbol# (ensure-symbol ~(:symbol-or-addr args))]
|
||||||
|
(def ~(:var-name args)
|
||||||
|
~@(when-let [doc (:docstring args)]
|
||||||
|
(list doc))
|
||||||
|
(static-variable symbol#)))))
|
||||||
|
(s/fdef defvar
|
||||||
|
:args ::defconst-args)
|
||||||
|
|
||||||
(s/def :coffi.ffi.symbolspec/symbol string?)
|
(s/def :coffi.ffi.symbolspec/symbol string?)
|
||||||
(s/def :coffi.ffi.symbolspec/type keyword?)
|
(s/def :coffi.ffi.symbolspec/type keyword?)
|
||||||
(s/def ::symbolspec
|
(s/def ::symbolspec
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue