Merge branch 'feature/jdk18-support' into develop
This commit is contained in:
commit
b8c9417d3f
6 changed files with 278 additions and 229 deletions
|
|
@ -2,6 +2,13 @@
|
||||||
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/).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Removed
|
||||||
|
- `:coffi.mem/long-long` primitive type
|
||||||
|
- `coffi.mem/slice-into`; the function no longer has an equivalent in panama, but see 2-arity of `coffi.mem/as-segment` for an alternative
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `coffi.mem/as-segment` no longer has a close action arity
|
||||||
|
- JDK version from 17 to 18
|
||||||
|
|
||||||
## [0.4.341] - 2022-01-23
|
## [0.4.341] - 2022-01-23
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,6 @@ Coffi defines a basic set of primitive types:
|
||||||
- short
|
- short
|
||||||
- int
|
- int
|
||||||
- long
|
- long
|
||||||
- long-long
|
|
||||||
- char
|
- char
|
||||||
- float
|
- float
|
||||||
- double
|
- double
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@
|
||||||
(b/process {:command-args ["javac" "--add-modules=jdk.incubator.foreign"
|
(b/process {:command-args ["javac" "--add-modules=jdk.incubator.foreign"
|
||||||
"src/java/coffi/ffi/Loader.java"
|
"src/java/coffi/ffi/Loader.java"
|
||||||
"-d" class-dir
|
"-d" class-dir
|
||||||
"-target" "17"
|
"-target" "18"
|
||||||
"-source" "17"]})
|
"-source" "18"]})
|
||||||
opts)
|
opts)
|
||||||
|
|
||||||
(defn- write-pom
|
(defn- write-pom
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
Addressable
|
Addressable
|
||||||
CLinker
|
CLinker
|
||||||
FunctionDescriptor
|
FunctionDescriptor
|
||||||
|
MemoryAddress
|
||||||
MemoryLayout
|
MemoryLayout
|
||||||
|
NativeSymbol
|
||||||
SegmentAllocator)))
|
SegmentAllocator)))
|
||||||
|
|
||||||
;;; FFI Code loading and function access
|
;;; FFI Code loading and function access
|
||||||
|
|
@ -33,18 +35,9 @@
|
||||||
(Loader/loadLibrary (.getAbsolutePath (io/file path))))
|
(Loader/loadLibrary (.getAbsolutePath (io/file path))))
|
||||||
|
|
||||||
(defn find-symbol
|
(defn find-symbol
|
||||||
"Gets the [[MemoryAddress]] of a symbol from the loaded libraries."
|
"Gets the [[NativeSymbol]] of a symbol from the loaded libraries."
|
||||||
[sym]
|
[sym]
|
||||||
(let [sym (name sym)]
|
(Loader/findSymbol (name sym)))
|
||||||
(Loader/findSymbol sym)))
|
|
||||||
|
|
||||||
(defn- method-type
|
|
||||||
"Gets the [[MethodType]] for a set of `args` and `ret` types."
|
|
||||||
([args] (method-type args ::mem/void))
|
|
||||||
([args ret]
|
|
||||||
(MethodType/methodType
|
|
||||||
^Class (mem/java-layout ret)
|
|
||||||
^"[Ljava.lang.Class;" (into-array Class (map mem/java-layout args)))))
|
|
||||||
|
|
||||||
(defn- function-descriptor
|
(defn- function-descriptor
|
||||||
"Gets the [[FunctionDescriptor]] for a set of `args` and `ret` types."
|
"Gets the [[FunctionDescriptor]] for a set of `args` and `ret` types."
|
||||||
|
|
@ -60,8 +53,8 @@
|
||||||
|
|
||||||
(defn- downcall-handle
|
(defn- downcall-handle
|
||||||
"Gets the [[MethodHandle]] for the function at the `address`."
|
"Gets the [[MethodHandle]] for the function at the `address`."
|
||||||
[address method-type function-descriptor]
|
[sym function-descriptor]
|
||||||
(.downcallHandle (CLinker/getInstance) address method-type function-descriptor))
|
(.downcallHandle (CLinker/systemCLinker) sym function-descriptor))
|
||||||
|
|
||||||
(def ^:private load-instructions
|
(def ^:private load-instructions
|
||||||
"Mapping from primitive types to the instruction used to load them onto the stack."
|
"Mapping from primitive types to the instruction used to load them onto the stack."
|
||||||
|
|
@ -138,6 +131,15 @@
|
||||||
[: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- coerce-addressable
|
||||||
|
"If the passed `type` is [[MemoryAddress]], returns [[Addressable]], otherwise returns `type`.
|
||||||
|
|
||||||
|
This is used to declare the return types of upcall stubs."
|
||||||
|
[type]
|
||||||
|
(if (= type MemoryAddress)
|
||||||
|
Addressable
|
||||||
|
type))
|
||||||
|
|
||||||
(defn- downcall-class
|
(defn- downcall-class
|
||||||
"Class definition for an implementation of [[IFn]] which calls a closed over
|
"Class definition for 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."
|
||||||
|
|
@ -174,7 +176,7 @@
|
||||||
args)
|
args)
|
||||||
[:invokevirtual MethodHandle "invokeExact"
|
[:invokevirtual MethodHandle "invokeExact"
|
||||||
(cond->>
|
(cond->>
|
||||||
(conj (mapv insn-layout args)
|
(conj (mapv (comp coerce-addressable insn-layout) args)
|
||||||
(insn-layout ret))
|
(insn-layout ret))
|
||||||
(not (mem/primitive-type ret)) (cons SegmentAllocator))]
|
(not (mem/primitive-type ret)) (cons SegmentAllocator))]
|
||||||
(to-object-asm ret)
|
(to-object-asm ret)
|
||||||
|
|
@ -185,12 +187,12 @@
|
||||||
[handle args ret]
|
[handle args ret]
|
||||||
(insn/new-instance (downcall-class args ret) ^MethodHandle handle))
|
(insn/new-instance (downcall-class args ret) ^MethodHandle handle))
|
||||||
|
|
||||||
(defn- ensure-address
|
(defn- ensure-symbol
|
||||||
"Gets the address if the argument is [[Addressable]], otherwise
|
"Gets the address if the argument is [[Addressable]], otherwise
|
||||||
calls [[find-symbol]] on it."
|
calls [[find-symbol]] on it."
|
||||||
[symbol-or-addr]
|
^NativeSymbol [symbol-or-addr]
|
||||||
(if (instance? Addressable symbol-or-addr)
|
(if (instance? NativeSymbol symbol-or-addr)
|
||||||
(mem/address-of symbol-or-addr)
|
symbol-or-addr
|
||||||
(find-symbol symbol-or-addr)))
|
(find-symbol symbol-or-addr)))
|
||||||
|
|
||||||
(defn make-downcall
|
(defn make-downcall
|
||||||
|
|
@ -205,10 +207,8 @@
|
||||||
first argument of a [[SegmentAllocator]]."
|
first argument of a [[SegmentAllocator]]."
|
||||||
[symbol-or-addr args ret]
|
[symbol-or-addr args ret]
|
||||||
(-> symbol-or-addr
|
(-> symbol-or-addr
|
||||||
ensure-address
|
ensure-symbol
|
||||||
(downcall-handle
|
(downcall-handle (function-descriptor args ret))
|
||||||
(method-type args ret)
|
|
||||||
(function-descriptor args ret))
|
|
||||||
(downcall-fn args ret)))
|
(downcall-fn args ret)))
|
||||||
|
|
||||||
(defn make-varargs-factory
|
(defn make-varargs-factory
|
||||||
|
|
@ -440,7 +440,7 @@
|
||||||
arguments."
|
arguments."
|
||||||
[symbol required-args ret]
|
[symbol required-args ret]
|
||||||
(-> symbol
|
(-> symbol
|
||||||
ensure-address
|
ensure-symbol
|
||||||
(make-varargs-factory required-args ret)
|
(make-varargs-factory required-args ret)
|
||||||
(make-serde-varargs-wrapper required-args ret)))
|
(make-serde-varargs-wrapper required-args ret)))
|
||||||
|
|
||||||
|
|
@ -452,7 +452,6 @@
|
||||||
::mem/short :sreturn
|
::mem/short :sreturn
|
||||||
::mem/int :ireturn
|
::mem/int :ireturn
|
||||||
::mem/long :lreturn
|
::mem/long :lreturn
|
||||||
::mem/long-long :lreturn
|
|
||||||
::mem/char :creturn
|
::mem/char :creturn
|
||||||
::mem/float :freturn
|
::mem/float :freturn
|
||||||
::mem/double :dreturn
|
::mem/double :dreturn
|
||||||
|
|
@ -460,7 +459,7 @@
|
||||||
|
|
||||||
(def ^:private double-sized?
|
(def ^:private double-sized?
|
||||||
"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/long-long})
|
#{::mem/double ::mem/long})
|
||||||
|
|
||||||
(defn- upcall-class
|
(defn- upcall-class
|
||||||
"Constructs a class definition for a class with a single method, `upcall`, which
|
"Constructs a class definition for a class with a single method, `upcall`, which
|
||||||
|
|
@ -482,7 +481,7 @@
|
||||||
{:name :upcall
|
{:name :upcall
|
||||||
:flags #{:public}
|
:flags #{:public}
|
||||||
:desc (conj (mapv insn-layout arg-types)
|
:desc (conj (mapv insn-layout arg-types)
|
||||||
(insn-layout ret-type))
|
(coerce-addressable (insn-layout ret-type)))
|
||||||
:emit [[:aload 0]
|
:emit [[:aload 0]
|
||||||
[:getfield :this "upcall_ifn" IFn]
|
[:getfield :this "upcall_ifn" IFn]
|
||||||
(loop [types arg-types
|
(loop [types arg-types
|
||||||
|
|
@ -498,7 +497,7 @@
|
||||||
inc)))
|
inc)))
|
||||||
acc))
|
acc))
|
||||||
[: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 (coerce-addressable ret-type))
|
||||||
[(return-for-type ret-type :areturn)]]}]})
|
[(return-for-type ret-type :areturn)]]}]})
|
||||||
|
|
||||||
(defn- upcall
|
(defn- upcall
|
||||||
|
|
@ -506,6 +505,17 @@
|
||||||
[f arg-types ret-type]
|
[f arg-types ret-type]
|
||||||
(insn/new-instance (upcall-class arg-types ret-type) ^IFn f))
|
(insn/new-instance (upcall-class arg-types ret-type) ^IFn f))
|
||||||
|
|
||||||
|
(defn- method-type
|
||||||
|
"Gets the [[MethodType]] for a set of `args` and `ret` types."
|
||||||
|
([args] (method-type args ::mem/void))
|
||||||
|
([args ret]
|
||||||
|
(MethodType/methodType
|
||||||
|
^Class (let [r (mem/java-layout ret)]
|
||||||
|
(if (= r MemoryAddress)
|
||||||
|
Addressable
|
||||||
|
r))
|
||||||
|
^"[Ljava.lang.Class;" (into-array Class (map mem/java-layout args)))))
|
||||||
|
|
||||||
(defn- upcall-handle
|
(defn- upcall-handle
|
||||||
"Constructs a method handle for invoking `f`, a function of `arg-count` args."
|
"Constructs a method handle for invoking `f`, a function of `arg-count` args."
|
||||||
[f arg-types ret-type]
|
[f arg-types ret-type]
|
||||||
|
|
@ -532,7 +542,7 @@
|
||||||
(defmethod mem/serialize* ::fn
|
(defmethod mem/serialize* ::fn
|
||||||
[f [_fn arg-types ret-type & {:keys [raw-fn?]}] scope]
|
[f [_fn arg-types ret-type & {:keys [raw-fn?]}] scope]
|
||||||
(.upcallStub
|
(.upcallStub
|
||||||
(CLinker/getInstance)
|
(CLinker/systemCLinker)
|
||||||
(cond-> f
|
(cond-> f
|
||||||
(not raw-fn?) (upcall-serde-wrapper arg-types ret-type)
|
(not raw-fn?) (upcall-serde-wrapper arg-types ret-type)
|
||||||
:always (upcall-handle arg-types ret-type))
|
:always (upcall-handle arg-types ret-type))
|
||||||
|
|
@ -544,9 +554,8 @@
|
||||||
(when-not (mem/null? addr)
|
(when-not (mem/null? addr)
|
||||||
(vary-meta
|
(vary-meta
|
||||||
(-> addr
|
(-> addr
|
||||||
(downcall-handle
|
(as-> addr (NativeSymbol/ofAddress "coffi_upcall_symbol" addr (mem/connected-scope)))
|
||||||
(method-type arg-types ret-type)
|
(downcall-handle (function-descriptor arg-types ret-type))
|
||||||
(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)))
|
||||||
|
|
@ -556,19 +565,16 @@
|
||||||
(defn const
|
(defn const
|
||||||
"Gets the value of a constant stored in `symbol-or-addr`."
|
"Gets the value of a constant stored in `symbol-or-addr`."
|
||||||
[symbol-or-addr type]
|
[symbol-or-addr type]
|
||||||
(mem/deserialize (ensure-address symbol-or-addr) [::mem/pointer type]))
|
(mem/deserialize (.address (ensure-symbol symbol-or-addr)) [::mem/pointer type]))
|
||||||
|
|
||||||
(deftype StaticVariable [addr type meta]
|
(deftype StaticVariable [seg type meta]
|
||||||
Addressable
|
|
||||||
(address [_]
|
|
||||||
addr)
|
|
||||||
IDeref
|
IDeref
|
||||||
(deref [_]
|
(deref [_]
|
||||||
(mem/deserialize addr [::mem/pointer type]))
|
(mem/deserialize seg type))
|
||||||
|
|
||||||
IObj
|
IObj
|
||||||
(withMeta [_ meta-map]
|
(withMeta [_ meta-map]
|
||||||
(StaticVariable. addr type (atom meta-map)))
|
(StaticVariable. seg type (atom meta-map)))
|
||||||
IMeta
|
IMeta
|
||||||
(meta [_]
|
(meta [_]
|
||||||
@meta)
|
@meta)
|
||||||
|
|
@ -583,7 +589,7 @@
|
||||||
[^StaticVariable static-var newval]
|
[^StaticVariable static-var newval]
|
||||||
(mem/serialize-into
|
(mem/serialize-into
|
||||||
newval (.-type static-var)
|
newval (.-type static-var)
|
||||||
(mem/slice-global (.-addr static-var) (mem/size-of (.-type static-var)))
|
(.-seg static-var)
|
||||||
(mem/global-scope))
|
(mem/global-scope))
|
||||||
newval)
|
newval)
|
||||||
|
|
||||||
|
|
@ -603,7 +609,10 @@
|
||||||
|
|
||||||
See [[freset!]], [[fswap!]]."
|
See [[freset!]], [[fswap!]]."
|
||||||
[symbol-or-addr type]
|
[symbol-or-addr type]
|
||||||
(StaticVariable. (ensure-address symbol-or-addr) type (atom nil)))
|
(StaticVariable. (mem/as-segment (.address (ensure-symbol symbol-or-addr))
|
||||||
|
(mem/size-of type)
|
||||||
|
(mem/global-scope))
|
||||||
|
type (atom nil)))
|
||||||
|
|
||||||
(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?)
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,13 @@
|
||||||
(java.nio ByteOrder)
|
(java.nio ByteOrder)
|
||||||
(jdk.incubator.foreign
|
(jdk.incubator.foreign
|
||||||
Addressable
|
Addressable
|
||||||
CLinker
|
|
||||||
MemoryAccess
|
|
||||||
MemoryAddress
|
MemoryAddress
|
||||||
MemoryLayout
|
MemoryLayout
|
||||||
MemorySegment
|
MemorySegment
|
||||||
ResourceScope
|
ResourceScope
|
||||||
ResourceScope$Handle
|
|
||||||
SegmentAllocator
|
SegmentAllocator
|
||||||
ValueLayout)))
|
ValueLayout
|
||||||
|
ValueLayout$OfAddress)))
|
||||||
|
|
||||||
(defn stack-scope
|
(defn stack-scope
|
||||||
"Constructs a new scope for use only in this thread.
|
"Constructs a new scope for use only in this thread.
|
||||||
|
|
@ -78,7 +76,7 @@
|
||||||
downcall function returns a non-primitive type, it must be provided with an
|
downcall function returns a non-primitive type, it must be provided with an
|
||||||
allocator."
|
allocator."
|
||||||
^SegmentAllocator [^ResourceScope scope]
|
^SegmentAllocator [^ResourceScope scope]
|
||||||
(SegmentAllocator/ofScope scope))
|
(SegmentAllocator/nativeAllocator scope))
|
||||||
|
|
||||||
(defn segment-scope
|
(defn segment-scope
|
||||||
"Gets the scope used to construct the `segment`."
|
"Gets the scope used to construct the `segment`."
|
||||||
|
|
@ -107,15 +105,10 @@
|
||||||
with it wrapped in this."
|
with it wrapped in this."
|
||||||
{:style/indent 1}
|
{:style/indent 1}
|
||||||
[scopes & body]
|
[scopes & body]
|
||||||
`(let [scopes# (vec ~scopes)
|
`(with-open [scope# (stack-scope)]
|
||||||
handles# (mapv #(.acquire ^ResourceScope %) scopes#)]
|
(doseq [target-scope# (vec ~scopes)]
|
||||||
(try ~@body
|
(.keepAlive scope# target-scope#))
|
||||||
(finally
|
~@body))
|
||||||
(doseq [idx# (range (count scopes#))
|
|
||||||
:let [scope# (nth scopes# idx#)
|
|
||||||
handle# (nth handles# idx#)]]
|
|
||||||
(.release ^ResourceScope scope#
|
|
||||||
^ResourceScope$Handle handle#))))))
|
|
||||||
(s/fdef with-acquired
|
(s/fdef with-acquired
|
||||||
:args (s/cat :scopes any?
|
:args (s/cat :scopes any?
|
||||||
:body (s/* any?)))
|
:body (s/* any?)))
|
||||||
|
|
@ -139,16 +132,6 @@
|
||||||
[addr]
|
[addr]
|
||||||
(or (nil? addr) (instance? MemoryAddress addr)))
|
(or (nil? addr) (instance? MemoryAddress addr)))
|
||||||
|
|
||||||
(defn slice-global
|
|
||||||
"Gets a slice of the global address space.
|
|
||||||
|
|
||||||
Because this fetches from the global segment, it has no associated scope, and
|
|
||||||
therefore the reference created here cannot prevent the value from being
|
|
||||||
freed. Be careful to ensure that you are not retaining an object incorrectly."
|
|
||||||
^MemorySegment [address size]
|
|
||||||
(.asSlice (MemorySegment/globalNativeSegment)
|
|
||||||
^MemoryAddress address (long size)))
|
|
||||||
|
|
||||||
(defn slice
|
(defn slice
|
||||||
"Get a slice over the `segment` with the given `offset`."
|
"Get a slice over the `segment` with the given `offset`."
|
||||||
(^MemorySegment [segment offset]
|
(^MemorySegment [segment offset]
|
||||||
|
|
@ -168,25 +151,19 @@
|
||||||
^MemoryAddress [address offset]
|
^MemoryAddress [address offset]
|
||||||
(.addOffset ^MemoryAddress address (long offset)))
|
(.addOffset ^MemoryAddress address (long offset)))
|
||||||
|
|
||||||
(defn as-segment
|
|
||||||
"Dereferences an `address` into a memory segment associated with the `scope`.
|
|
||||||
|
|
||||||
If `cleanup` is provided, it is a 0-arity function run when the scope is
|
|
||||||
closed. This can be used to register a free method for the memory, or do other
|
|
||||||
cleanup in a way that doesn't require modifying the code at the point of
|
|
||||||
freeing, and allows shared or garbage collected resources to be freed
|
|
||||||
correctly."
|
|
||||||
(^MemorySegment [^MemoryAddress address size scope]
|
|
||||||
(.asSegment address (long size) scope))
|
|
||||||
(^MemorySegment [^MemoryAddress address size ^ResourceScope scope cleanup]
|
|
||||||
(.asSegment address (long size) cleanup scope)))
|
|
||||||
|
|
||||||
(defn add-close-action!
|
(defn add-close-action!
|
||||||
"Adds a 0-arity function to be run when the `scope` closes."
|
"Adds a 0-arity function to be run when the `scope` closes."
|
||||||
[^ResourceScope scope ^Runnable action]
|
[^ResourceScope scope ^Runnable action]
|
||||||
(.addCloseAction scope action)
|
(.addCloseAction scope action)
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
(defn as-segment
|
||||||
|
"Dereferences an `address` into a memory segment associated with the `scope`."
|
||||||
|
(^MemorySegment [^MemoryAddress address size]
|
||||||
|
(MemorySegment/ofAddress address (long size) (connected-scope)))
|
||||||
|
(^MemorySegment [^MemoryAddress address size scope]
|
||||||
|
(MemorySegment/ofAddress address (long size) scope)))
|
||||||
|
|
||||||
(defn copy-segment
|
(defn copy-segment
|
||||||
"Copies the content to `dest` from `src`.
|
"Copies the content to `dest` from `src`.
|
||||||
|
|
||||||
|
|
@ -230,39 +207,35 @@
|
||||||
|
|
||||||
(def ^ValueLayout byte-layout
|
(def ^ValueLayout byte-layout
|
||||||
"The [[MemoryLayout]] for a byte in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a byte in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_CHAR)
|
(MemoryLayout/valueLayout Byte/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout short-layout
|
(def ^ValueLayout short-layout
|
||||||
"The [[MemoryLayout]] for a c-sized short in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized short in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_SHORT)
|
(MemoryLayout/valueLayout Short/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout int-layout
|
(def ^ValueLayout int-layout
|
||||||
"The [[MemoryLayout]] for a c-sized int in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized int in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_INT)
|
(MemoryLayout/valueLayout Integer/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout long-layout
|
(def ^ValueLayout long-layout
|
||||||
"The [[MemoryLayout]] for a c-sized long in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized long in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_LONG)
|
(MemoryLayout/valueLayout Long/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout long-long-layout
|
|
||||||
"The [[MemoryLayout]] for a c-sized long-long in [[native-endian]] [[ByteOrder]]."
|
|
||||||
CLinker/C_LONG_LONG)
|
|
||||||
|
|
||||||
(def ^ValueLayout char-layout
|
(def ^ValueLayout char-layout
|
||||||
"The [[MemoryLayout]] for a c-sized char in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized char in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_CHAR)
|
(MemoryLayout/valueLayout Byte/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout float-layout
|
(def ^ValueLayout float-layout
|
||||||
"The [[MemoryLayout]] for a c-sized float in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized float in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_FLOAT)
|
(MemoryLayout/valueLayout Float/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout double-layout
|
(def ^ValueLayout double-layout
|
||||||
"The [[MemoryLayout]] for a c-sized double in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a c-sized double in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_DOUBLE)
|
(MemoryLayout/valueLayout Double/TYPE native-endian))
|
||||||
|
|
||||||
(def ^ValueLayout pointer-layout
|
(def ^ValueLayout$OfAddress pointer-layout
|
||||||
"The [[MemoryLayout]] for a native pointer in [[native-endian]] [[ByteOrder]]."
|
"The [[MemoryLayout]] for a native pointer in [[native-endian]] [[ByteOrder]]."
|
||||||
CLinker/C_POINTER)
|
ValueLayout/ADDRESS)
|
||||||
|
|
||||||
(def ^long short-size
|
(def ^long short-size
|
||||||
"The size in bytes of a c-sized short."
|
"The size in bytes of a c-sized short."
|
||||||
|
|
@ -276,10 +249,6 @@
|
||||||
"The size in bytes of a c-sized long."
|
"The size in bytes of a c-sized long."
|
||||||
(.byteSize long-layout))
|
(.byteSize long-layout))
|
||||||
|
|
||||||
(def ^long long-long-size
|
|
||||||
"The size in bytes of a c-sized long long."
|
|
||||||
(.byteSize long-long-layout))
|
|
||||||
|
|
||||||
(def ^long float-size
|
(def ^long float-size
|
||||||
"The size in bytes of a c-sized float."
|
"The size in bytes of a c-sized float."
|
||||||
(.byteSize float-layout))
|
(.byteSize float-layout))
|
||||||
|
|
@ -304,10 +273,6 @@
|
||||||
"The alignment in bytes of a c-sized long."
|
"The alignment in bytes of a c-sized long."
|
||||||
(.byteAlignment long-layout))
|
(.byteAlignment long-layout))
|
||||||
|
|
||||||
(def ^long long-long-alignment
|
|
||||||
"The alignment in bytes of a c-sized long long."
|
|
||||||
(.byteAlignment long-long-layout))
|
|
||||||
|
|
||||||
(def ^long float-alignment
|
(def ^long float-alignment
|
||||||
"The alignment in bytes of a c-sized float."
|
"The alignment in bytes of a c-sized float."
|
||||||
(.byteAlignment float-layout))
|
(.byteAlignment float-layout))
|
||||||
|
|
@ -325,13 +290,16 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-byte-inline
|
(fn read-byte-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getByte ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout byte-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getByteAtOffset ~segment ~offset)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout byte-layout offset#))))}
|
||||||
([^MemorySegment segment]
|
([^MemorySegment segment]
|
||||||
(MemoryAccess/getByte segment))
|
(.get segment ^ValueLayout byte-layout 0))
|
||||||
([^MemorySegment segment ^long offset]
|
([^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getByteAtOffset segment offset)))
|
(.get segment ^ValueLayout byte-layout offset)))
|
||||||
|
|
||||||
(defn read-short
|
(defn read-short
|
||||||
"Reads a [[short]] from the `segment`, at an optional `offset`.
|
"Reads a [[short]] from the `segment`, at an optional `offset`.
|
||||||
|
|
@ -340,17 +308,23 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-short-inline
|
(fn read-short-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getShort ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout short-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getShortAtOffset ~segment ~offset))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout short-layout offset#)))
|
||||||
([segment offset byte-order]
|
([segment offset byte-order]
|
||||||
`(MemoryAccess/getShortAtOffset ~segment ~offset ~byte-order)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order]
|
||||||
|
(.get ^MemorySegment segment# (.withOrder ^ValueLayout short-layout ^ByteOrder byte-order#) offset#))))}
|
||||||
([^MemorySegment segment]
|
([^MemorySegment segment]
|
||||||
(MemoryAccess/getShort segment))
|
(.get segment ^ValueLayout short-layout 0))
|
||||||
([^MemorySegment segment ^long offset]
|
([^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getShortAtOffset segment offset))
|
(.get segment ^ValueLayout short-layout offset))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
||||||
(MemoryAccess/getShortAtOffset segment offset byte-order)))
|
(.get segment (.withOrder ^ValueLayout short-layout byte-order) offset)))
|
||||||
|
|
||||||
(defn read-int
|
(defn read-int
|
||||||
"Reads a [[int]] from the `segment`, at an optional `offset`.
|
"Reads a [[int]] from the `segment`, at an optional `offset`.
|
||||||
|
|
@ -359,17 +333,23 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-int-inline
|
(fn read-int-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getInt ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout int-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getIntAtOffset ~segment ~offset))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout int-layout offset#)))
|
||||||
([segment offset byte-order]
|
([segment offset byte-order]
|
||||||
`(MemoryAccess/getIntAtOffset ~segment ~offset ~byte-order)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order]
|
||||||
|
(.get ^MemorySegment segment# (.withOrder ^ValueLayout int-layout ^ByteOrder byte-order#) offset#))))}
|
||||||
([^MemorySegment segment]
|
([^MemorySegment segment]
|
||||||
(MemoryAccess/getInt segment))
|
(.get segment ^ValueLayout int-layout 0))
|
||||||
([^MemorySegment segment ^long offset]
|
([^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getIntAtOffset segment offset))
|
(.get segment ^ValueLayout int-layout offset))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
||||||
(MemoryAccess/getIntAtOffset segment offset byte-order)))
|
(.get segment (.withOrder ^ValueLayout int-layout byte-order) offset)))
|
||||||
|
|
||||||
(defn read-long
|
(defn read-long
|
||||||
"Reads a [[long]] from the `segment`, at an optional `offset`.
|
"Reads a [[long]] from the `segment`, at an optional `offset`.
|
||||||
|
|
@ -378,30 +358,39 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-long-inline
|
(fn read-long-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getLong ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout long-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getLongAtOffset ~segment ~offset))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout long-layout offset#)))
|
||||||
([segment offset byte-order]
|
([segment offset byte-order]
|
||||||
`(MemoryAccess/getLongAtOffset ~segment ~offset ~byte-order)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order]
|
||||||
|
(.get ^MemorySegment segment# (.withOrder ^ValueLayout long-layout ^ByteOrder byte-order#) offset#))))}
|
||||||
(^long [^MemorySegment segment]
|
(^long [^MemorySegment segment]
|
||||||
(MemoryAccess/getLong segment))
|
(.get segment ^ValueLayout long-layout 0))
|
||||||
(^long [^MemorySegment segment ^long offset]
|
(^long [^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getLongAtOffset segment offset))
|
(.get segment ^ValueLayout long-layout offset))
|
||||||
(^long [^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
(^long [^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
||||||
(MemoryAccess/getLongAtOffset segment offset byte-order)))
|
(.get segment (.withOrder ^ValueLayout long-layout byte-order) offset)))
|
||||||
|
|
||||||
(defn read-char
|
(defn read-char
|
||||||
"Reads a [[char]] from the `segment`, at an optional `offset`."
|
"Reads a [[char]] from the `segment`, at an optional `offset`."
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-char-inline
|
(fn read-char-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(char (Byte/toUnsignedInt (MemoryAccess/getByte ~segment))))
|
`(let [segment# ~segment]
|
||||||
|
(char (Byte/toUnsignedInt (.get ^MemorySegment segment# ^ValueLayout byte-layout 0)))))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(char (Byte/toUnsignedInt (MemoryAccess/getByteAtOffset ~segment ~offset)))))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(char (Byte/toUnsignedInt (.get ^MemorySegment segment# ^ValueLayout byte-layout offset#))))))}
|
||||||
([^MemorySegment segment]
|
([^MemorySegment segment]
|
||||||
(char (Byte/toUnsignedInt (MemoryAccess/getByte segment))))
|
(char (Byte/toUnsignedInt (.get segment ^ValueLayout byte-layout 0))))
|
||||||
([^MemorySegment segment ^long offset]
|
([^MemorySegment segment ^long offset]
|
||||||
(char (Byte/toUnsignedInt (MemoryAccess/getByteAtOffset segment offset)))))
|
(char (Byte/toUnsignedInt (.get segment ^ValueLayout byte-layout offset)))))
|
||||||
|
|
||||||
(defn read-float
|
(defn read-float
|
||||||
"Reads a [[float]] from the `segment`, at an optional `offset`.
|
"Reads a [[float]] from the `segment`, at an optional `offset`.
|
||||||
|
|
@ -410,17 +399,23 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-float-inline
|
(fn read-float-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getFloat ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout float-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getFloatAtOffset ~segment ~offset))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout float-layout offset#)))
|
||||||
([segment offset byte-order]
|
([segment offset byte-order]
|
||||||
`(MemoryAccess/getFloatAtOffset ~segment ~offset ~byte-order)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order]
|
||||||
|
(.get ^MemorySegment segment# (.withOrder ^ValueLayout float-layout ^ByteOrder byte-order#) offset#))))}
|
||||||
([^MemorySegment segment]
|
([^MemorySegment segment]
|
||||||
(MemoryAccess/getFloat segment))
|
(.get segment ^ValueLayout float-layout 0))
|
||||||
([^MemorySegment segment ^long offset]
|
([^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getFloatAtOffset segment offset))
|
(.get segment ^ValueLayout float-layout offset))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
||||||
(MemoryAccess/getFloatAtOffset segment offset byte-order)))
|
(.get segment (.withOrder ^ValueLayout float-layout byte-order) offset)))
|
||||||
|
|
||||||
(defn read-double
|
(defn read-double
|
||||||
"Reads a [[double]] from the `segment`, at an optional `offset`.
|
"Reads a [[double]] from the `segment`, at an optional `offset`.
|
||||||
|
|
@ -429,43 +424,57 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-double-inline
|
(fn read-double-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getDouble ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout double-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getDoubleAtOffset ~segment ~offset))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout double-layout offset#)))
|
||||||
([segment offset byte-order]
|
([segment offset byte-order]
|
||||||
`(MemoryAccess/getDoubleAtOffset ~segment ~offset ~byte-order)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order]
|
||||||
|
(.get ^MemorySegment segment# (.withOrder ^ValueLayout double-layout ^ByteOrder byte-order#) offset#))))}
|
||||||
(^double [^MemorySegment segment]
|
(^double [^MemorySegment segment]
|
||||||
(MemoryAccess/getDouble segment))
|
(.get segment ^ValueLayout double-layout 0))
|
||||||
(^double [^MemorySegment segment ^long offset]
|
(^double [^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getDoubleAtOffset segment offset))
|
(.get segment ^ValueLayout double-layout offset))
|
||||||
(^double [^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
(^double [^MemorySegment segment ^long offset ^ByteOrder byte-order]
|
||||||
(MemoryAccess/getDoubleAtOffset segment offset byte-order)))
|
(.get segment (.withOrder ^ValueLayout double-layout byte-order) offset)))
|
||||||
|
|
||||||
(defn read-address
|
(defn read-address
|
||||||
"Reads a [[MemoryAddress]] from the `segment`, at an optional `offset`."
|
"Reads a [[MemoryAddress]] from the `segment`, at an optional `offset`."
|
||||||
{:inline
|
{:inline
|
||||||
(fn read-address-inline
|
(fn read-address-inline
|
||||||
([segment]
|
([segment]
|
||||||
`(MemoryAccess/getAddress ~segment))
|
`(let [segment# ~segment]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout$OfAddress pointer-layout 0)))
|
||||||
([segment offset]
|
([segment offset]
|
||||||
`(MemoryAccess/getAddressAtOffset ~segment ~offset)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset]
|
||||||
|
(.get ^MemorySegment segment# ^ValueLayout$OfAddress pointer-layout offset#))))}
|
||||||
(^MemoryAddress [^MemorySegment segment]
|
(^MemoryAddress [^MemorySegment segment]
|
||||||
(MemoryAccess/getAddress segment))
|
(.get segment ^ValueLayout$OfAddress pointer-layout 0))
|
||||||
(^MemoryAddress [^MemorySegment segment ^long offset]
|
(^MemoryAddress [^MemorySegment segment ^long offset]
|
||||||
(MemoryAccess/getAddressAtOffset segment offset)))
|
(.get segment ^ValueLayout$OfAddress pointer-layout offset)))
|
||||||
|
|
||||||
(defn write-byte
|
(defn write-byte
|
||||||
"Writes a [[byte]] to the `segment`, at an optional `offset`."
|
"Writes a [[byte]] to the `segment`, at an optional `offset`."
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-byte-inline
|
(fn write-byte-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setByte ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout byte-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setByteAtOffset ~segment ~offset ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout byte-layout offset# value#))))}
|
||||||
([^MemorySegment segment value]
|
([^MemorySegment segment value]
|
||||||
(MemoryAccess/setByte segment ^byte value))
|
(.set segment ^ValueLayout byte-layout 0 ^byte value))
|
||||||
([^MemorySegment segment ^long offset value]
|
([^MemorySegment segment ^long offset value]
|
||||||
(MemoryAccess/setByteAtOffset segment offset ^byte value)))
|
(.set segment ^ValueLayout byte-layout offset ^byte value)))
|
||||||
|
|
||||||
(defn write-short
|
(defn write-short
|
||||||
"Writes a [[short]] to the `segment`, at an optional `offset`.
|
"Writes a [[short]] to the `segment`, at an optional `offset`.
|
||||||
|
|
@ -474,17 +483,26 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-short-inline
|
(fn write-short-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setShort ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout short-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setShortAtOffset ~segment ~offset ~value))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout short-layout offset# value#)))
|
||||||
([segment offset byte-order value]
|
([segment offset byte-order value]
|
||||||
`(MemoryAccess/setShortAtOffset ~segment ~offset ~byte-order ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# (.withOrder ^ValueLayout short-layout ^ByteOrder byte-order#) offset# value#))))}
|
||||||
([^MemorySegment segment value]
|
([^MemorySegment segment value]
|
||||||
(MemoryAccess/setShort segment ^short value))
|
(.set segment ^ValueLayout short-layout 0 ^short value))
|
||||||
([^MemorySegment segment ^long offset value]
|
([^MemorySegment segment ^long offset value]
|
||||||
(MemoryAccess/setShortAtOffset segment offset ^short value))
|
(.set segment ^ValueLayout short-layout offset ^short value))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
||||||
(MemoryAccess/setShortAtOffset segment offset byte-order ^short value)))
|
(.set segment (.withOrder ^ValueLayout short-layout byte-order) offset ^short value)))
|
||||||
|
|
||||||
(defn write-int
|
(defn write-int
|
||||||
"Writes a [[int]] to the `segment`, at an optional `offset`.
|
"Writes a [[int]] to the `segment`, at an optional `offset`.
|
||||||
|
|
@ -493,17 +511,26 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-int-inline
|
(fn write-int-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setInt ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout int-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setIntAtOffset ~segment ~offset ~value))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout int-layout offset# value#)))
|
||||||
([segment offset byte-order value]
|
([segment offset byte-order value]
|
||||||
`(MemoryAccess/setIntAtOffset ~segment ~offset ~byte-order ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# (.withOrder ^ValueLayout int-layout ^ByteOrder byte-order#) offset# value#))))}
|
||||||
([^MemorySegment segment value]
|
([^MemorySegment segment value]
|
||||||
(MemoryAccess/setInt segment ^int value))
|
(.set segment ^ValueLayout int-layout 0 ^int value))
|
||||||
([^MemorySegment segment ^long offset value]
|
([^MemorySegment segment ^long offset value]
|
||||||
(MemoryAccess/setIntAtOffset segment offset ^int value))
|
(.set segment ^ValueLayout int-layout offset ^int value))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
||||||
(MemoryAccess/setIntAtOffset segment offset byte-order ^int value)))
|
(.set segment (.withOrder ^ValueLayout int-layout byte-order) offset ^int value)))
|
||||||
|
|
||||||
(defn write-long
|
(defn write-long
|
||||||
"Writes a [[long]] to the `segment`, at an optional `offset`.
|
"Writes a [[long]] to the `segment`, at an optional `offset`.
|
||||||
|
|
@ -512,35 +539,50 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-long-inline
|
(fn write-long-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setLong ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout long-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setLongAtOffset ~segment ~offset ~value))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout long-layout offset# value#)))
|
||||||
([segment offset byte-order value]
|
([segment offset byte-order value]
|
||||||
`(MemoryAccess/setLongAtOffset ~segment ~offset ~byte-order ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# (.withOrder ^ValueLayout long-layout ^ByteOrder byte-order#) offset# value#))))}
|
||||||
(^long [^MemorySegment segment ^long value]
|
(^long [^MemorySegment segment ^long value]
|
||||||
(MemoryAccess/setLong segment value))
|
(.set segment ^ValueLayout long-layout 0 value))
|
||||||
(^long [^MemorySegment segment ^long offset ^long value]
|
(^long [^MemorySegment segment ^long offset ^long value]
|
||||||
(MemoryAccess/setLongAtOffset segment offset value))
|
(.set segment ^ValueLayout long-layout offset value))
|
||||||
(^long [^MemorySegment segment ^long offset ^ByteOrder byte-order ^long value]
|
(^long [^MemorySegment segment ^long offset ^ByteOrder byte-order ^long value]
|
||||||
(MemoryAccess/setLongAtOffset segment offset byte-order value)))
|
(.set segment (.withOrder ^ValueLayout long-layout byte-order) offset value)))
|
||||||
|
|
||||||
(defn write-char
|
(defn write-char
|
||||||
"Writes a [[char]] to the `segment`, at an optional `offset`."
|
"Writes a [[char]] to the `segment`, at an optional `offset`."
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-char-inline
|
(fn write-char-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setByte ~segment (unchecked-byte (unchecked-int ~value))))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout byte-layout 0 (unchecked-byte (unchecked-int value#)))))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setByteAtOffset ~segment ~offset (unchecked-byte (unchecked-int ~value)))))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout byte-layout offset# (unchecked-byte (unchecked-int value#))))))}
|
||||||
([^MemorySegment segment value]
|
([^MemorySegment segment value]
|
||||||
(MemoryAccess/setByte
|
(.set
|
||||||
segment
|
segment
|
||||||
;; HACK(Joshua): The Clojure runtime doesn't have an unchecked-byte cast for
|
;; HACK(Joshua): The Clojure runtime doesn't have an unchecked-byte cast for
|
||||||
;; characters, so this double cast is necessary unless I emit
|
;; characters, so this double cast is necessary unless I emit
|
||||||
;; my own bytecode with insn.
|
;; my own bytecode with insn.
|
||||||
|
^ValueLayout byte-layout 0
|
||||||
(unchecked-byte (unchecked-int ^char value))))
|
(unchecked-byte (unchecked-int ^char value))))
|
||||||
([^MemorySegment segment ^long offset value]
|
([^MemorySegment segment ^long offset value]
|
||||||
(MemoryAccess/setByteAtOffset segment offset (unchecked-byte (unchecked-int ^char value)))))
|
(.set segment ^ValueLayout byte-layout offset (unchecked-byte (unchecked-int ^char value)))))
|
||||||
|
|
||||||
(defn write-float
|
(defn write-float
|
||||||
"Writes a [[float]] to the `segment`, at an optional `offset`.
|
"Writes a [[float]] to the `segment`, at an optional `offset`.
|
||||||
|
|
@ -549,17 +591,26 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-float-inline
|
(fn write-float-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setFloat ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout float-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setFloatAtOffset ~segment ~offset ~value))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout float-layout offset# value#)))
|
||||||
([segment offset byte-order value]
|
([segment offset byte-order value]
|
||||||
`(MemoryAccess/setFloatAtOffset ~segment ~offset ~byte-order ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# (.withOrder ^ValueLayout float-layout ^ByteOrder byte-order#) offset# value#))))}
|
||||||
([^MemorySegment segment value]
|
([^MemorySegment segment value]
|
||||||
(MemoryAccess/setFloat segment ^float value))
|
(.set segment ^ValueLayout float-layout 0 ^float value))
|
||||||
([^MemorySegment segment ^long offset value]
|
([^MemorySegment segment ^long offset value]
|
||||||
(MemoryAccess/setFloatAtOffset segment offset ^float value))
|
(.set segment ^ValueLayout float-layout offset ^float value))
|
||||||
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
|
||||||
(MemoryAccess/setFloatAtOffset segment offset byte-order ^float value)))
|
(.set segment (.withOrder ^ValueLayout float-layout byte-order) offset ^float value)))
|
||||||
|
|
||||||
(defn write-double
|
(defn write-double
|
||||||
"Writes a [[double]] to the `segment`, at an optional `offset`.
|
"Writes a [[double]] to the `segment`, at an optional `offset`.
|
||||||
|
|
@ -568,30 +619,44 @@
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-double-inline
|
(fn write-double-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setDouble ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout double-layout 0 value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setDoubleAtOffset ~segment ~offset ~value))
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout double-layout offset# value#)))
|
||||||
([segment offset byte-order value]
|
([segment offset byte-order value]
|
||||||
`(MemoryAccess/setDoubleAtOffset ~segment ~offset ~byte-order ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
byte-order# ~byte-order
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# (.withOrder ^ValueLayout double-layout ^ByteOrder byte-order#) offset# value#))))}
|
||||||
(^double [^MemorySegment segment ^double value]
|
(^double [^MemorySegment segment ^double value]
|
||||||
(MemoryAccess/setDouble segment value))
|
(.set segment ^ValueLayout double-layout 0 value))
|
||||||
(^double [^MemorySegment segment ^long offset ^double value]
|
(^double [^MemorySegment segment ^long offset ^double value]
|
||||||
(MemoryAccess/setDoubleAtOffset segment offset value))
|
(.set segment ^ValueLayout double-layout offset value))
|
||||||
(^double [^MemorySegment segment ^long offset ^ByteOrder byte-order ^double value]
|
(^double [^MemorySegment segment ^long offset ^ByteOrder byte-order ^double value]
|
||||||
(MemoryAccess/setDoubleAtOffset segment offset byte-order value)))
|
(.set segment (.withOrder ^ValueLayout double-layout byte-order) offset value)))
|
||||||
|
|
||||||
(defn write-address
|
(defn write-address
|
||||||
"Writes a [[MemoryAddress]] to the `segment`, at an optional `offset`."
|
"Writes a [[MemoryAddress]] to the `segment`, at an optional `offset`."
|
||||||
{:inline
|
{:inline
|
||||||
(fn write-address-inline
|
(fn write-address-inline
|
||||||
([segment value]
|
([segment value]
|
||||||
`(MemoryAccess/setAddress ~segment ~value))
|
`(let [segment# ~segment
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout$OfAddress pointer-layout 0 ^Addressable value#)))
|
||||||
([segment offset value]
|
([segment offset value]
|
||||||
`(MemoryAccess/setAddressAtOffset ~segment ~offset ~value)))}
|
`(let [segment# ~segment
|
||||||
|
offset# ~offset
|
||||||
|
value# ~value]
|
||||||
|
(.set ^MemorySegment segment# ^ValueLayout$OfAddress pointer-layout offset# ^Addressable value#))))}
|
||||||
(^MemoryAddress [^MemorySegment segment ^MemoryAddress value]
|
(^MemoryAddress [^MemorySegment segment ^MemoryAddress value]
|
||||||
(MemoryAccess/setAddress segment value))
|
(.set segment ^ValueLayout$OfAddress pointer-layout 0 value))
|
||||||
(^MemoryAddress [^MemorySegment segment ^long offset ^MemoryAddress value]
|
(^MemoryAddress [^MemorySegment segment ^long offset ^MemoryAddress value]
|
||||||
(MemoryAccess/setAddressAtOffset segment offset value)))
|
(.set segment ^ValueLayout$OfAddress pointer-layout offset value)))
|
||||||
|
|
||||||
(defn- type-dispatch
|
(defn- type-dispatch
|
||||||
"Gets a type dispatch value from a (potentially composite) type."
|
"Gets a type dispatch value from a (potentially composite) type."
|
||||||
|
|
@ -603,7 +668,7 @@
|
||||||
|
|
||||||
(def primitive-types
|
(def primitive-types
|
||||||
"A set of all primitive types."
|
"A set of all primitive types."
|
||||||
#{::byte ::short ::int ::long ::long-long
|
#{::byte ::short ::int ::long
|
||||||
::char ::float ::double ::pointer})
|
::char ::float ::double ::pointer})
|
||||||
|
|
||||||
(defn primitive?
|
(defn primitive?
|
||||||
|
|
@ -644,10 +709,6 @@
|
||||||
[_type]
|
[_type]
|
||||||
::long)
|
::long)
|
||||||
|
|
||||||
(defmethod primitive-type ::long-long
|
|
||||||
[_type]
|
|
||||||
::long-long)
|
|
||||||
|
|
||||||
(defmethod primitive-type ::char
|
(defmethod primitive-type ::char
|
||||||
[_type]
|
[_type]
|
||||||
::char)
|
::char)
|
||||||
|
|
@ -688,27 +749,21 @@
|
||||||
(defmethod c-layout ::short
|
(defmethod c-layout ::short
|
||||||
[type]
|
[type]
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(.withOrder short-layout (second type))
|
(.withOrder short-layout ^ByteOrder (second type))
|
||||||
short-layout))
|
short-layout))
|
||||||
|
|
||||||
(defmethod c-layout ::int
|
(defmethod c-layout ::int
|
||||||
[type]
|
[type]
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(.withOrder int-layout (second type))
|
(.withOrder int-layout ^ByteOrder (second type))
|
||||||
int-layout))
|
int-layout))
|
||||||
|
|
||||||
(defmethod c-layout ::long
|
(defmethod c-layout ::long
|
||||||
[type]
|
[type]
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(.withOrder long-layout (second type))
|
(.withOrder long-layout ^ByteOrder (second type))
|
||||||
long-layout))
|
long-layout))
|
||||||
|
|
||||||
(defmethod c-layout ::long-long
|
|
||||||
[type]
|
|
||||||
(if (sequential? type)
|
|
||||||
(.withOrder long-long-layout (second type))
|
|
||||||
long-long-layout))
|
|
||||||
|
|
||||||
(defmethod c-layout ::char
|
(defmethod c-layout ::char
|
||||||
[_type]
|
[_type]
|
||||||
char-layout)
|
char-layout)
|
||||||
|
|
@ -716,13 +771,13 @@
|
||||||
(defmethod c-layout ::float
|
(defmethod c-layout ::float
|
||||||
[type]
|
[type]
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(.withOrder float-layout (second type))
|
(.withOrder float-layout ^ByteOrder (second type))
|
||||||
float-layout))
|
float-layout))
|
||||||
|
|
||||||
(defmethod c-layout ::double
|
(defmethod c-layout ::double
|
||||||
[type]
|
[type]
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(.withOrder double-layout (second type))
|
(.withOrder double-layout ^ByteOrder (second type))
|
||||||
double-layout))
|
double-layout))
|
||||||
|
|
||||||
(defmethod c-layout ::pointer
|
(defmethod c-layout ::pointer
|
||||||
|
|
@ -735,7 +790,6 @@
|
||||||
::short Short/TYPE
|
::short Short/TYPE
|
||||||
::int Integer/TYPE
|
::int Integer/TYPE
|
||||||
::long Long/TYPE
|
::long Long/TYPE
|
||||||
::long-long Long/TYPE
|
|
||||||
::char Byte/TYPE
|
::char Byte/TYPE
|
||||||
::float Float/TYPE
|
::float Float/TYPE
|
||||||
::double Double/TYPE
|
::double Double/TYPE
|
||||||
|
|
@ -805,10 +859,6 @@
|
||||||
[obj _type _scope]
|
[obj _type _scope]
|
||||||
(long obj))
|
(long obj))
|
||||||
|
|
||||||
(defmethod serialize* ::long-long
|
|
||||||
[obj _type _scope]
|
|
||||||
(long obj))
|
|
||||||
|
|
||||||
(defmethod serialize* ::char
|
(defmethod serialize* ::char
|
||||||
[obj _type _scope]
|
[obj _type _scope]
|
||||||
(char obj))
|
(char obj))
|
||||||
|
|
@ -886,12 +936,6 @@
|
||||||
(write-long segment 0 (second type) (long obj))
|
(write-long segment 0 (second type) (long obj))
|
||||||
(write-long segment (long obj))))
|
(write-long segment (long obj))))
|
||||||
|
|
||||||
(defmethod serialize-into ::long-long
|
|
||||||
[obj type segment _scope]
|
|
||||||
(if (sequential? type)
|
|
||||||
(write-long segment 0 (second type) (long obj))
|
|
||||||
(write-long segment (long obj))))
|
|
||||||
|
|
||||||
(defmethod serialize-into ::char
|
(defmethod serialize-into ::char
|
||||||
[obj _type segment _scope]
|
[obj _type segment _scope]
|
||||||
(write-char segment (char obj)))
|
(write-char segment (char obj)))
|
||||||
|
|
@ -911,7 +955,7 @@
|
||||||
(defmethod serialize-into ::pointer
|
(defmethod serialize-into ::pointer
|
||||||
[obj type segment scope]
|
[obj type segment scope]
|
||||||
(with-acquired [(segment-scope segment) scope]
|
(with-acquired [(segment-scope segment) scope]
|
||||||
(MemoryAccess/setAddress
|
(write-address
|
||||||
segment
|
segment
|
||||||
(cond-> obj
|
(cond-> obj
|
||||||
(sequential? type) (serialize* type scope)))))
|
(sequential? type) (serialize* type scope)))))
|
||||||
|
|
@ -977,12 +1021,6 @@
|
||||||
(read-long segment 0 (second type))
|
(read-long segment 0 (second type))
|
||||||
(read-long segment)))
|
(read-long segment)))
|
||||||
|
|
||||||
(defmethod deserialize-from ::long-long
|
|
||||||
[segment type]
|
|
||||||
(if (sequential? type)
|
|
||||||
(read-long segment 0 (second type))
|
|
||||||
(read-long segment)))
|
|
||||||
|
|
||||||
(defmethod deserialize-from ::char
|
(defmethod deserialize-from ::char
|
||||||
[segment _type]
|
[segment _type]
|
||||||
(read-char segment))
|
(read-char segment))
|
||||||
|
|
@ -1002,7 +1040,7 @@
|
||||||
(defmethod deserialize-from ::pointer
|
(defmethod deserialize-from ::pointer
|
||||||
[segment type]
|
[segment type]
|
||||||
(with-acquired [(segment-scope segment)]
|
(with-acquired [(segment-scope segment)]
|
||||||
(cond-> (MemoryAccess/getAddress segment)
|
(cond-> (read-address segment)
|
||||||
(sequential? type) (deserialize* type))))
|
(sequential? type) (deserialize* type))))
|
||||||
|
|
||||||
(defmulti deserialize*
|
(defmulti deserialize*
|
||||||
|
|
@ -1037,10 +1075,6 @@
|
||||||
[obj _type]
|
[obj _type]
|
||||||
obj)
|
obj)
|
||||||
|
|
||||||
(defmethod deserialize* ::long-long
|
|
||||||
[obj _type]
|
|
||||||
obj)
|
|
||||||
|
|
||||||
(defmethod deserialize* ::char
|
(defmethod deserialize* ::char
|
||||||
[obj _type]
|
[obj _type]
|
||||||
obj)
|
obj)
|
||||||
|
|
@ -1057,7 +1091,7 @@
|
||||||
[addr type]
|
[addr type]
|
||||||
(when-not (null? addr)
|
(when-not (null? addr)
|
||||||
(if (sequential? type)
|
(if (sequential? type)
|
||||||
(deserialize-from (slice-global addr (size-of (second type)))
|
(deserialize-from (as-segment addr (size-of (second type)))
|
||||||
(second type))
|
(second type))
|
||||||
addr)))
|
addr)))
|
||||||
|
|
||||||
|
|
@ -1092,13 +1126,13 @@
|
||||||
(defmethod serialize* ::c-string
|
(defmethod serialize* ::c-string
|
||||||
[obj _type scope]
|
[obj _type scope]
|
||||||
(if obj
|
(if obj
|
||||||
(address-of (CLinker/toCString ^String obj ^ResourceScope scope))
|
(address-of (.allocateUtf8String (scope-allocator scope) ^String obj))
|
||||||
(MemoryAddress/NULL)))
|
(MemoryAddress/NULL)))
|
||||||
|
|
||||||
(defmethod deserialize* ::c-string
|
(defmethod deserialize* ::c-string
|
||||||
[addr _type]
|
[addr _type]
|
||||||
(when-not (null? addr)
|
(when-not (null? addr)
|
||||||
(CLinker/toJavaString ^MemoryAddress addr)))
|
(.getUtf8String ^MemoryAddress addr 0)))
|
||||||
|
|
||||||
;;; Union types
|
;;; Union types
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ public class Loader {
|
||||||
*
|
*
|
||||||
* @param symbol The name of the symbol to load from a library.
|
* @param symbol The name of the symbol to load from a library.
|
||||||
*/
|
*/
|
||||||
public static MemoryAddress findSymbol(String symbol) {
|
public static NativeSymbol findSymbol(String symbol) {
|
||||||
return CLinker.systemLookup().lookup(symbol)
|
return CLinker.systemCLinker().lookup(symbol)
|
||||||
.orElseGet(() -> SymbolLookup.loaderLookup().lookup(symbol).orElse(null));
|
.orElseGet(() -> SymbolLookup.loaderLookup().lookup(symbol).orElse(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue