This commit is contained in:
Kristin Rutenkolk 2025-03-03 15:06:07 -06:00 committed by GitHub
commit 1a3f2e6bee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 151 additions and 32 deletions

View file

@ -61,6 +61,7 @@
(def ^:private load-instructions
"Mapping from primitive types to the instruction used to load them onto the stack."
{::mem/byte :bload
::mem/boolean :iload ; as per jvms 2.3.4 it should be iload. hmm
::mem/short :sload
::mem/int :iload
::mem/long :lload
@ -72,6 +73,7 @@
(def ^:private prim-classes
"Mapping from primitive types to their box classes."
{::mem/byte Byte
::mem/boolean Boolean
::mem/short Short
::mem/int Integer
::mem/long Long
@ -107,6 +109,7 @@
(def ^:private unbox-fn-for-type
"Map from type name to the name of its unboxing function."
{::mem/byte "byteValue"
::mem/boolean "booleanValue"
::mem/short "shortValue"
::mem/int "intValue"
::mem/long "longValue"
@ -240,6 +243,7 @@
"Map from non-pointer primitive types to functions that cast to the appropriate
java primitive."
{::mem/byte `byte
::mem/boolean `boolean
::mem/short `short
::mem/int `int
::mem/long `long
@ -467,6 +471,7 @@
(def ^:private return-for-type
"Map from type name to the return instruction for that type."
{::mem/byte :breturn
::mem/boolean :ireturn
::mem/short :sreturn
::mem/int :ireturn
::mem/long :lreturn

View file

@ -27,6 +27,7 @@
SegmentAllocator
ValueLayout
ValueLayout$OfByte
ValueLayout$OfBoolean
ValueLayout$OfShort
ValueLayout$OfInt
ValueLayout$OfLong
@ -209,6 +210,10 @@
"The [[MemoryLayout]] for a byte in [[native-endian]] [[ByteOrder]]."
ValueLayout/JAVA_BYTE)
(def ^ValueLayout$OfBoolean boolean-layout
"The [[MemoryLayout]] for a boolean in [[native-endian]] [[ByteOrder]]."
ValueLayout/JAVA_BOOLEAN)
(def ^ValueLayout$OfShort short-layout
"The [[MemoryLayout]] for a c-sized short in [[native-endian]] [[ByteOrder]]."
ValueLayout/JAVA_SHORT)
@ -237,6 +242,10 @@
"The [[MemoryLayout]] for a native pointer in [[native-endian]] [[ByteOrder]]."
ValueLayout/ADDRESS)
(def ^long boolean-size
"The size in bytes of a c-sized boolean."
(.byteSize boolean-layout))
(def ^long short-size
"The size in bytes of a c-sized short."
(.byteSize short-layout))
@ -261,6 +270,10 @@
"The size in bytes of a c-sized pointer."
(.byteSize pointer-layout))
(def ^long boolean-alignment
"The alignment in bytes of a c-sized boolean."
(.byteAlignment boolean-layout))
(def ^long short-alignment
"The alignment in bytes of a c-sized short."
(.byteAlignment short-layout))
@ -286,7 +299,7 @@
(.byteAlignment pointer-layout))
(def ^:private primitive-tag?
'#{byte bytes short shorts int ints long longs
'#{byte boolean bytes short shorts int ints long longs
float floats double doubles
bool bools char chars})
@ -319,6 +332,31 @@
([^MemorySegment segment ^long offset]
(.get segment ^ValueLayout$OfByte byte-layout offset)))
(defn read-boolean
"Reads a [[boolean]] from the `segment`, at an optional `offset`.
If `byte-order` is not provided, it defaults to [[native-endian]]."
{:inline
(fn read-boolean-inline
([segment]
`(let [segment# ~segment]
(.get ^MemorySegment segment# ^ValueLayout$OfBoolean boolean-layout 0)))
([segment offset]
`(let [segment# ~segment
offset# ~offset]
(.get ^MemorySegment segment# ^ValueLayout$OfBoolean boolean-layout offset#)))
([segment offset byte-order]
`(let [segment# ~segment
offset# ~offset
byte-order# ~byte-order]
(.get ^MemorySegment segment# (.withOrder ^ValueLayout$OfBoolean boolean-layout ^ByteOrder byte-order#) offset#))))}
([^MemorySegment segment]
(.get segment ^ValueLayout$OfBoolean boolean-layout 0))
([^MemorySegment segment ^long offset]
(.get segment ^ValueLayout$OfBoolean boolean-layout offset))
([^MemorySegment segment ^long offset ^ByteOrder byte-order]
(.get segment (.withOrder ^ValueLayout$OfBoolean boolean-layout byte-order) offset)))
(defn read-short
"Reads a [[short]] from the `segment`, at an optional `offset`.
@ -491,6 +529,29 @@
([^MemorySegment segment ^long offset value]
(.set segment ^ValueLayout$OfByte byte-layout offset ^byte value)))
(defn write-boolean
"Writes a [[boolean]] to the `segment`, at an optional `offset`.
If `byte-order` is not provided, it defaults to [[native-endian]]."
{:inline
(fn write-boolean-inline
([segment value]
(once-only [^java.lang.foreign.MemorySegment segment ^boolean value]
`(.set ~segment ^ValueLayout$OfBoolean boolean-layout 0 ~value)))
([segment offset value]
(once-only [^java.lang.foreign.MemorySegment segment ^long offset ^boolean value]
`(.set ~segment ^ValueLayout$OfBoolean boolean-layout ~offset ~value)))
([segment offset byte-order value]
(once-only [^java.lang.foreign.MemorySegment segment ^long offset
^java.nio.ByteOrder byte-order ^boolean value]
`(.set ~segment (.withOrder ^ValueLayout$OfBoolean boolean-layout ~byte-order) ~offset ~value))))}
([^MemorySegment segment value]
(.set segment ^ValueLayout$OfBoolean boolean-layout 0 ^boolean value))
([^MemorySegment segment ^long offset value]
(.set segment ^ValueLayout$OfBoolean boolean-layout offset ^boolean value))
([^MemorySegment segment ^long offset ^ByteOrder byte-order value]
(.set segment (.withOrder ^ValueLayout$OfBoolean boolean-layout byte-order) offset ^boolean value)))
(defn write-short
"Writes a [[short]] to the `segment`, at an optional `offset`.
@ -659,6 +720,23 @@
([^MemorySegment segment n offset ^bytes value]
(MemorySegment/copy value 0 segment ^ValueLayout$OfByte byte-layout ^long offset ^int n)))
(defn write-booleans
"Writes n elements from a [[boolean]] array to the `segment`, at an optional `offset`.
If `byte-order` is not provided, it defaults to [[native-endian]]."
{:inline
(fn write-boolean-inline
([segment n value]
(once-only [^java.lang.foreign.MemorySegment segment ^booleans value]
`(MemorySegment/copy ~value 0 ~segment ^ValueLayout$OfBoolean boolean-layout 0 ~n)))
([segment n offset value]
(once-only [^java.lang.foreign.MemorySegment segment ^long offset ^booleans value]
`(MemorySegment/copy ~value 0 ~segment ^ValueLayout$OfBoolean boolean-layout ~offset ~n))))}
([^MemorySegment segment n ^booleans value]
(MemorySegment/copy value 0 segment ^ValueLayout$OfBoolean boolean-layout 0 ^int n))
([^MemorySegment segment n ^long offset ^booleans value]
(MemorySegment/copy value 0 segment ^ValueLayout$OfBoolean boolean-layout ^long offset ^int n)))
(defn write-shorts
"Writes n elements from a [[short]] array to the `segment`, at an optional `offset`.
@ -1038,7 +1116,7 @@
(def primitive-types
"A set of all primitive types."
#{::byte ::short ::int ::long
#{::byte ::boolean ::short ::int ::long
::char ::float ::double ::pointer})
(defn primitive?
@ -1067,6 +1145,10 @@
[_type]
::byte)
(defmethod primitive-type ::boolean
[_type]
::boolean)
(defmethod primitive-type ::short
[_type]
::short)
@ -1116,6 +1198,12 @@
[_type]
byte-layout)
(defmethod c-layout ::boolean
[type]
(if (sequential? type)
(.withOrder boolean-layout ^ByteOrder (second type))
boolean-layout))
(defmethod c-layout ::short
[type]
(if (sequential? type)
@ -1157,6 +1245,7 @@
(def java-prim-layout
"Map of primitive type names to the Java types for a method handle."
{::byte Byte/TYPE
::boolean Boolean/TYPE
::short Short/TYPE
::int Integer/TYPE
::long Long/TYPE
@ -1217,6 +1306,10 @@
[obj _type _arena]
(byte obj))
(defmethod serialize* ::boolean
[obj _type _arena]
(boolean obj))
(defmethod serialize* ::short
[obj _type _arena]
(short obj))
@ -1284,6 +1377,12 @@
[obj _type segment _arena]
(write-byte segment obj))
(defmethod serialize-into ::boolean
[obj type segment _arena]
(if (sequential? type)
(write-boolean segment 0 (second type) (boolean obj))
(write-boolean segment (boolean obj))))
(defmethod serialize-into ::short
[obj type segment _arena]
(if (sequential? type)
@ -1366,6 +1465,12 @@
[segment _type]
(read-byte segment))
(defmethod deserialize-from ::boolean
[segment type]
(if (sequential? type)
(read-boolean segment 0 (second type))
(read-boolean segment)))
(defmethod deserialize-from ::short
[segment type]
(if (sequential? type)
@ -1425,6 +1530,10 @@
[obj _type]
obj)
(defmethod deserialize* ::boolean
[obj _type]
obj)
(defmethod deserialize* ::short
[obj _type]
obj)
@ -1733,14 +1842,16 @@
(let [[indirect-type type n & {:keys [raw?] :as opts}] (if (vector? in) in [:- in])
arr? (= indirect-type ::array)
ptr? (= indirect-type ::pointer)
array-types {::byte 'bytes
::short 'shorts
::int 'ints
::long 'longs
::char 'chars
::float 'floats
::double 'doubles}
array-types {::byte 'bytes
::boolean 'booleans
::short 'shorts
::int 'ints
::long 'longs
::char 'chars
::float 'floats
::double 'doubles}
single-types {::byte 'byte
::boolean 'boolean
::short 'short
::int 'int
::long 'long
@ -1755,37 +1866,41 @@
(defn- coffitype->array-fn [type]
(get
{:coffi.mem/byte `byte-array
:coffi.mem/short `short-array
:coffi.mem/int `int-array
:coffi.mem/long `long-array
:coffi.mem/char `char-array
:coffi.mem/float `float-array
:coffi.mem/double `double-array}
{:coffi.mem/byte `byte-array
:coffi.mem/boolean `boolean-array
:coffi.mem/short `short-array
:coffi.mem/int `int-array
:coffi.mem/long `long-array
:coffi.mem/char `char-array
:coffi.mem/float `float-array
:coffi.mem/double `double-array}
type
`object-array))
(defn- coffitype->array-write-fn [type]
({:coffi.mem/byte `write-bytes
:coffi.mem/short `write-shorts
:coffi.mem/int `write-ints
:coffi.mem/long `write-longs
:coffi.mem/char `write-chars
:coffi.mem/float `write-floats
:coffi.mem/double `write-doubles} type))
({:coffi.mem/byte `write-bytes
:coffi.mem/boolean `write-booleans
:coffi.mem/short `write-shorts
:coffi.mem/int `write-ints
:coffi.mem/long `write-longs
:coffi.mem/char `write-chars
:coffi.mem/float `write-floats
:coffi.mem/double `write-doubles} type))
(defn- coffitype->array-read-fn [type]
({:coffi.mem/byte `read-bytes
:coffi.mem/short `read-shorts
:coffi.mem/int `read-ints
:coffi.mem/long `read-longs
:coffi.mem/char `read-chars
:coffi.mem/float `read-floats
:coffi.mem/double `read-doubles} type))
({:coffi.mem/byte `read-bytes
:coffi.mem/boolean `read-shorts
:coffi.mem/short `read-shorts
:coffi.mem/int `read-ints
:coffi.mem/long `read-longs
:coffi.mem/char `read-chars
:coffi.mem/float `read-floats
:coffi.mem/double `read-doubles} type))
(defmulti generate-deserialize (fn [& xs] (if (vector? (first xs)) (ffirst xs) (first xs))))
(defmethod generate-deserialize :coffi.mem/byte [_type offset segment-source-form] `(read-byte ~segment-source-form ~offset))
(defmethod generate-deserialize :coffi.mem/boolean [_type offset segment-source-form] `(read-boolean ~segment-source-form ~offset))
(defmethod generate-deserialize :coffi.mem/short [_type offset segment-source-form] `(read-short ~segment-source-form ~offset))
(defmethod generate-deserialize :coffi.mem/int [_type offset segment-source-form] `(read-int ~segment-source-form ~offset))
(defmethod generate-deserialize :coffi.mem/long [_type offset segment-source-form] `(read-long ~segment-source-form ~offset))
@ -1861,6 +1976,7 @@
(defmulti generate-serialize (fn [& xs] (if (vector? (first xs)) (ffirst xs) (first xs))))
(defmethod generate-serialize :coffi.mem/byte [_type source-form offset segment-source-form] `(write-byte ~segment-source-form ~offset ~source-form))
(defmethod generate-serialize :coffi.mem/boolean [_type source-form offset segment-source-form] `(write-boolean ~segment-source-form ~offset ~source-form))
(defmethod generate-serialize :coffi.mem/short [_type source-form offset segment-source-form] `(write-short ~segment-source-form ~offset ~source-form))
(defmethod generate-serialize :coffi.mem/int [_type source-form offset segment-source-form] `(write-int ~segment-source-form ~offset ~source-form))
(defmethod generate-serialize :coffi.mem/long [_type source-form offset segment-source-form] `(write-long ~segment-source-form ~offset ~source-form))
@ -2227,5 +2343,3 @@
~(generate-serialize coffi-typename (with-meta 'source-obj {:tag typename}) 0 segment-form))
(defmethod clojure.pprint/simple-dispatch ~typename [~'obj] (clojure.pprint/simple-dispatch (into {} ~'obj)))
(defmethod clojure.core/print-method ~typename [~'obj ~'writer] (print-simple (into {} ~'obj) ~'writer)))))))