add :raw-arrays? option

This commit is contained in:
Kristin Rutenkolk 2024-10-30 20:28:20 +01:00
parent 69a99d5521
commit 56a0df3257

View file

@ -1573,6 +1573,12 @@
(pos? r) (conj [::padding [::padding (- strongest-alignment r)]])))))] (pos? r) (conj [::padding [::padding (- strongest-alignment r)]])))))]
(assoc struct-spec 1 aligned-fields))) (assoc struct-spec 1 aligned-fields)))
(defmethod c-layout ::vector-array
[[_vector-array type count]]
(MemoryLayout/sequenceLayout
count
(c-layout type)))
(defn- typename->coffi-typename [_type] (defn- typename->coffi-typename [_type]
(get (get
{'byte ::byte {'byte ::byte
@ -1592,9 +1598,11 @@
_type _type
(keyword (str *ns*) (str _type)))) (keyword (str *ns*) (str _type))))
(defn- coffitype->typename [_type] (defn- coffitype->typename [_type raw-arrays?]
(cond (cond
(and (vector? _type) (= ::array (first _type))) (get {::byte 'bytes (and (vector? _type)
(= ::array (first _type))
raw-arrays?) (get {::byte 'bytes
::short 'shorts ::short 'shorts
::int 'ints ::int 'ints
::long 'longs ::long 'longs
@ -1602,6 +1610,9 @@
::float 'floats ::float 'floats
::double 'doubles} ::double 'doubles}
(second _type) 'objects) (second _type) 'objects)
(and (vector? _type)
(= ::array (first _type))
(not raw-arrays?)) `clojure.lang.IPersistentVector
:default (get {::byte 'byte :default (get {::byte 'byte
::short 'short ::short 'short
::int 'int ::int 'int
@ -1646,15 +1657,24 @@
(generate-deserialize (generate-deserialize
(second _type) (second _type)
(+ offset (* (size-of (second _type)) index)))] (+ offset (* (size-of (second _type)) index)))]
(list `aset gen-arr index (first deserialize-instructions)) (list `aset gen-arr index (first deserialize-instructions))))
#_(if true #_(vector? deserialize-instructions)
(list index (first deserialize-instructions))
(list index deserialize-instructions))
))
(range (second (rest _type)))) (range (second (rest _type))))
[gen-arr])])) [gen-arr])]))
(defmethod generate-deserialize :coffi.mem/vector-array [_type offset]
(let [outer-code `(let [arr# (~(coffitype->array-fn (second _type)) ~(second (rest _type)))] arr# )
gen-arr (nth outer-code 2)]
[(concat (butlast outer-code)
(map
(fn [index]
(let [deserialize-instructions
(generate-deserialize
(second _type)
(+ offset (* (size-of (second _type)) index)))]
(list `aset gen-arr index (first deserialize-instructions))))
(range (second (rest _type))))
[(list `vec gen-arr)])]))
(defn typelist [typename fields] (defn typelist [typename fields]
(->> (->>
(partition 2 2 (interleave (reductions + 0 (map (comp size-of second) fields)) fields)) (partition 2 2 (interleave (reductions + 0 (map (comp size-of second) fields)) fields))
@ -1669,8 +1689,7 @@
(generate-deserialize field-type (+ global-offset offset)))) (generate-deserialize field-type (+ global-offset offset))))
(reduce concat) (reduce concat)
(cons (symbol (str (name typename) "."))) (cons (symbol (str (name typename) ".")))
(list) (list)))))
))))
(defmulti generate-serialize (fn [& xs] (if (vector? (first xs)) (first (first xs)) (first xs)))) (defmulti generate-serialize (fn [& xs] (if (vector? (first xs)) (first (first xs)) (first xs))))
@ -1694,6 +1713,16 @@
(+ offset (* (size-of member-type) index)))) (+ offset (* (size-of member-type) index))))
(range length)))) (range length))))
(defmethod generate-serialize :coffi.mem/vector-array [[_arr member-type length] source-form offset]
(concat
(list `let ['array-obj source-form])
(map
(fn [index]
(generate-serialize member-type
(list `nth 'array-obj index)
(+ offset (* (size-of member-type) index))))
(range length))))
(defn register-new-struct-serialization [typename [_struct fields]] (defn register-new-struct-serialization [typename [_struct fields]]
(let [typelist (typelist typename fields) (let [typelist (typelist typename fields)
fieldnames (filter #(not= ::padding %) (map first fields))] fieldnames (filter #(not= ::padding %) (map first fields))]
@ -1951,7 +1980,7 @@
This creates needed serialization and deserialization implementations for the new type." This creates needed serialization and deserialization implementations for the new type."
{:style/indent [:defn]} {:style/indent [:defn]}
[typename members] [typename members & {:keys [raw-arrays?] :or {raw-arrays? true} :as opts}]
(let [invalid-typenames (filter #(try (c-layout (first %)) nil (catch Exception e (first %))) (partition 2 members))] (let [invalid-typenames (filter #(try (c-layout (first %)) nil (catch Exception e (first %))) (partition 2 members))]
(cond (cond
(odd? (count members)) (throw (Exception. "uneven amount of members supplied. members have to be typed and are required to be supplied in the form of `typename member-name`. the typename has to be coffi typename, like `:coffi.mem/int` or `[:coffi.mem/array :coffi.mem/byte 3]`")) (odd? (count members)) (throw (Exception. "uneven amount of members supplied. members have to be typed and are required to be supplied in the form of `typename member-name`. the typename has to be coffi typename, like `:coffi.mem/int` or `[:coffi.mem/array :coffi.mem/byte 3]`"))
@ -1961,13 +1990,14 @@
typed-symbols (->> typed-symbols (->>
members members
(partition 2 2) (partition 2 2)
(map (fn [[_type sym]] (with-meta sym {:tag (coffitype->typename _type)}))) (map (fn [[_type sym]] (with-meta sym {:tag (coffitype->typename _type raw-arrays?)})))
(vec)) (vec))
struct-layout (with-c-layout [::struct struct-layout (with-c-layout [::struct
(->> (->>
members members
(partition 2 2) (partition 2 2)
(map vec) (map vec)
(clojure.walk/postwalk (if raw-arrays? identity #(if (= % ::array) ::vector-array %)))
(map #(update % 1 keyword)) (map #(update % 1 keyword))
(map reverse) (map reverse)
(map vec))])] (map vec))])]