Merge remote-tracking branch 'rutenkolk/master' into develop
This commit is contained in:
commit
00faaaa78b
5 changed files with 1114 additions and 87 deletions
|
|
@ -21,11 +21,11 @@
|
|||
(recur (cond-> (+ offset size)
|
||||
(pos? r) (+ (- align r)))
|
||||
(cond-> aligned-fields
|
||||
(pos? r) (conj [::padding [::mem/padding (- align r)]])
|
||||
(pos? r) (conj [:coffi.layout/padding [:coffi.mem/padding (- align r)]])
|
||||
:always (conj field))
|
||||
fields))
|
||||
(let [strongest-alignment (reduce max (map (comp mem/align-of second) (nth struct-spec 1)))
|
||||
r (rem offset strongest-alignment)]
|
||||
(cond-> aligned-fields
|
||||
(pos? r) (conj [::padding [::mem/padding (- strongest-alignment r)]])))))]
|
||||
(pos? r) (conj [:coffi.layout/padding [:coffi.mem/padding (- strongest-alignment r)]])))))]
|
||||
(assoc struct-spec 1 aligned-fields)))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -100,3 +100,24 @@ void free_variable_length_array(float *arr) {
|
|||
freed = 1;
|
||||
free(arr);
|
||||
}
|
||||
|
||||
typedef struct complextype {
|
||||
Point x;
|
||||
char y;
|
||||
int z[4];
|
||||
char *w;
|
||||
} ComplexType;
|
||||
|
||||
ComplexType complexTypeTest(ComplexType a) {
|
||||
ComplexType ret = {};
|
||||
ret.x = a.x;
|
||||
ret.x.x++;
|
||||
ret.x.y++;
|
||||
ret.y = a.y-1;
|
||||
ret.z[0] = a.z[0];
|
||||
ret.z[1] = a.z[1];
|
||||
ret.z[2] = a.z[2];
|
||||
ret.z[3] = a.z[3];
|
||||
ret.w = "hello from c";
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
[clojure.test :as t]
|
||||
[coffi.ffi :as ffi]
|
||||
[coffi.layout :as layout]
|
||||
[coffi.mem :as mem]))
|
||||
[coffi.mem :as mem]
|
||||
[clojure.pprint]))
|
||||
|
||||
(ffi/load-library "target/ffi_test.so")
|
||||
|
||||
|
|
@ -103,3 +104,33 @@
|
|||
(free-variable-length-array* floats-addr)))))]
|
||||
(t/is (not (zero? @freed?)))
|
||||
(t/is (= floats (mapv #(* (float 1.5) %) (range (count floats)))))))
|
||||
|
||||
(mem/defstruct Point [x ::mem/float y ::mem/float])
|
||||
|
||||
(t/deftest can-call-with-defstruct
|
||||
(t/is (= {:x 2.0 :y 2.0}
|
||||
((ffi/cfn "add_points" [::Point ::Point] ::Point) (Point. 1 2) (Point. 1 0)))))
|
||||
|
||||
(mem/defstruct AlignmentTest [a ::mem/char x ::mem/double y ::mem/float])
|
||||
|
||||
(t/deftest padding-matches-defstruct
|
||||
(t/is (= ((ffi/cfn "get_struct" [] ::AlignmentTest))
|
||||
{:a \x
|
||||
:x 3.14
|
||||
:y 42.0})))
|
||||
|
||||
(mem/defstruct ComplexType [x ::Point y ::mem/byte z [::mem/array ::mem/int 4 :raw? true] w ::mem/c-string])
|
||||
|
||||
(t/deftest can-call-with-complex-defstruct
|
||||
(t/are [x y] (= x (y ((ffi/cfn "complexTypeTest" [::ComplexType] ::ComplexType)
|
||||
(ComplexType. (Point. 2 3) 4 (int-array [5 6 7 8]) "hello from clojure"))))
|
||||
{:x {:x 3.0 :y 4.0} :y 3 :w "hello from c"} #(dissoc % :z)
|
||||
[5 6 7 8] (comp vec :z)))
|
||||
|
||||
(mem/defstruct ComplexTypeWrapped [x ::Point y ::mem/byte z [::mem/array ::mem/int 4] w ::mem/c-string])
|
||||
|
||||
(t/deftest can-call-with-wrapped-complex-defstruct
|
||||
(t/are [x y] (= x (y ((ffi/cfn "complexTypeTest" [::ComplexTypeWrapped] ::ComplexTypeWrapped)
|
||||
(ComplexTypeWrapped. (Point. 2 3) 4 (int-array [5 6 7 8]) "hello from clojure"))))
|
||||
{:x {:x 3.0 :y 4.0} :y 3 :w "hello from c"} #(dissoc % :z)
|
||||
[5 6 7 8] (comp vec :z)))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
(:require
|
||||
[clojure.test :as t]
|
||||
[coffi.ffi :as ffi]
|
||||
[coffi.layout :as layout]
|
||||
[coffi.mem :as mem])
|
||||
(:import
|
||||
(java.lang.foreign
|
||||
|
|
@ -29,4 +28,108 @@
|
|||
(t/is
|
||||
(instance? MemorySegment (mem/serialize "this is a string" ::mem/c-string))))
|
||||
|
||||
(t/deftest can-define-struct
|
||||
(t/is
|
||||
(eval
|
||||
`(mem/defstruct ~'TestType [~'a ::mem/int ~'b ::mem/byte]))))
|
||||
|
||||
(mem/defstruct TestType [a ::mem/int b ::mem/byte c ::mem/short])
|
||||
|
||||
(t/deftest can-initialize-struct
|
||||
(t/is (TestType. 5 10 15)))
|
||||
|
||||
(t/deftest can-use-common-map-functions
|
||||
(let [v1 (TestType. 5 10 15)
|
||||
v2 (TestType. 6 11 16)]
|
||||
(t/are [x y] (= x (y v1))
|
||||
5 :a
|
||||
10 :b
|
||||
15 :c
|
||||
5 (fn [v] (v :a))
|
||||
10 (fn [v] (v :b))
|
||||
15 (fn [v] (v :c))
|
||||
5 #(get % :a)
|
||||
10 #(get % :b)
|
||||
15 #(get % :c)
|
||||
20 #(get % :d 20)
|
||||
nil #(get % :d)
|
||||
[:a :b :c] keys
|
||||
[5 10 15] vals
|
||||
{:a 5 :c 15} #(dissoc % :b)
|
||||
{:a 5 :b 10 :c 0} #(assoc % :c 0)
|
||||
{:a 5 :b 10 :c 15 :d 20} #(assoc % :d 20)
|
||||
[[:a 5] [:b 10] [:c 15]] seq
|
||||
{:a 5 :b 10 :c 15 :d 20} #(merge % {:d 20})
|
||||
{:a [5 6] :b [10 11] :c [15 16]} #(merge-with vector % {:a 6 :b 11 :c 16})
|
||||
{:a [5 6] :b [10 11] :c [15 16]} #(merge-with vector % v2)
|
||||
[:a 5] #(find % :a)
|
||||
nil #(find % :d)
|
||||
{:a 5 :b 10 :c 15} identity
|
||||
v1 identity
|
||||
v1 (fn [s] {:a 5 :b 10 :c 15}))))
|
||||
|
||||
(t/deftest can-serialize-struct-type
|
||||
(t/is
|
||||
(instance? MemorySegment (mem/serialize (TestType. 5 10 15) ::TestType))))
|
||||
|
||||
(t/deftest can-deserialize-struct-type
|
||||
(t/is
|
||||
(= {:a 5 :b 10 :c 15}
|
||||
(mem/deserialize (mem/serialize (TestType. 5 10 15) ::TestType) ::TestType))))
|
||||
|
||||
(mem/defstruct NestedTestType [x ::mem/int y ::mem/byte z ::TestType])
|
||||
|
||||
(t/deftest can-instantiated-nested-structs
|
||||
(t/is
|
||||
(= {:x 5 :y 6 :z {:a 5 :b 10 :c 15}}
|
||||
(NestedTestType. 5 6 (TestType. 5 10 15)))))
|
||||
|
||||
(t/deftest can-define-structs-with-array-members
|
||||
(t/is
|
||||
(eval
|
||||
`(mem/defstruct ~'ArrayTestType [~'x ::mem/int ~'y ::mem/byte ~'z [::mem/array ::mem/int 4 :raw? true]]))))
|
||||
|
||||
(mem/defstruct ArrayTestType [x ::mem/int y ::mem/byte z [::mem/array ::mem/int 4 :raw? true]])
|
||||
|
||||
(t/deftest can-instantiated-array-member-structs
|
||||
(t/are [x y z] (z x (y (ArrayTestType. 5 6 (int-array [1 2 3 4]))))
|
||||
{:x 5 :y 6} #(dissoc % :z) =
|
||||
(int-array [1 2 3 4]) :z java.util.Arrays/equals))
|
||||
|
||||
(t/deftest can-serialize-array-struct
|
||||
(t/is
|
||||
(= [5 6 1 2 3 4]
|
||||
(vec (filter #(not= 0 %) (vec (.toArray (mem/serialize (ArrayTestType. 5 6 (int-array [1 2 3 4])) ::ArrayTestType) mem/byte-layout)))))))
|
||||
|
||||
(t/deftest can-serialize-deserialize-array-struct
|
||||
(t/is
|
||||
(java.util.Arrays/equals
|
||||
(int-array [1 2 3 4])
|
||||
(.z (mem/deserialize (mem/serialize (ArrayTestType. 5 6 (int-array [1 2 3 4])) ::ArrayTestType) ::ArrayTestType)))))
|
||||
|
||||
(mem/defstruct ComplexTestType [x [::mem/array ::ArrayTestType 4 :raw? true] y ::mem/byte z [::mem/array ::mem/int 4 :raw? true] w ::NestedTestType])
|
||||
|
||||
(t/deftest can-serialize-deserialize-complex-struct-type
|
||||
(t/is
|
||||
(let [x (object-array (map #(ArrayTestType. % % (int-array (range 4))) (range 4)))
|
||||
y 12
|
||||
z (int-array (range 4))
|
||||
w (NestedTestType. 5 6 (TestType. 5 10 15))]
|
||||
(->
|
||||
(ComplexTestType. x y z w)
|
||||
(mem/serialize ::ComplexTestType)
|
||||
(mem/deserialize ::ComplexTestType)))))
|
||||
|
||||
(mem/defstruct ComplexTestTypeWrapped [x [::mem/array ::ArrayTestType 4] y ::mem/byte z [::mem/array ::mem/int 4] w ::NestedTestType])
|
||||
|
||||
(t/deftest can-serialize-deserialize-complex-wrapped-struct-type
|
||||
(t/is
|
||||
(let [x (vec (map #(ArrayTestType. % % (int-array (range 4))) (range 4)))
|
||||
y 12
|
||||
z (vec (range 4))
|
||||
w (NestedTestType. 5 6 (TestType. 5 10 15))]
|
||||
(->
|
||||
(ComplexTestTypeWrapped. x y z w)
|
||||
(mem/serialize ::ComplexTestTypeWrapped)
|
||||
(mem/deserialize ::ComplexTestTypeWrapped)))))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue