diff --git a/test/c/ffi_test.c b/test/c/ffi_test.c index 24e6959..21095cf 100644 --- a/test/c/ffi_test.c +++ b/test/c/ffi_test.c @@ -1,4 +1,5 @@ #include +#include int add_numbers(int a, int b) { return a + b; @@ -78,3 +79,20 @@ void test_call_with_trailing_string_arg(int a, int b, char* text) { return; } +int freed = 0; + +int get_variable_length_array(float **arr) { + freed = 0; + *arr = malloc(sizeof(float) * 7); + + for (int i = 0; i < 7; ++i) { + (*arr)[i] = 1.5f * i; + } + + return 7; +} + +void free_variable_length_array(float *arr) { + freed = 1; + free(arr); +} diff --git a/test/clj/coffi/ffi_test.clj b/test/clj/coffi/ffi_test.clj index b462191..cc44347 100644 --- a/test/clj/coffi/ffi_test.clj +++ b/test/clj/coffi/ffi_test.clj @@ -70,3 +70,27 @@ (catch Throwable _t :err)) :ok))) + +(ffi/defvar freed? "freed" ::mem/int) + +(def get-variable-length-array* (ffi/make-downcall "get_variable_length_array" [::mem/pointer] ::mem/int)) +(def free-variable-length-array* (ffi/make-downcall "free_variable_length_array" [::mem/pointer] ::mem/void)) + +(t/deftest get-variable-length-array + (let [floats + (with-open [stack (mem/confined-arena)] + (let [out-floats (mem/alloc mem/pointer-size stack) + num-floats (get-variable-length-array* out-floats) + floats-addr (mem/read-address out-floats) + floats-slice (mem/reinterpret floats-addr (unchecked-multiply-int mem/float-size num-floats))] + (try + (loop [floats (transient []) + index 0] + (if (>= index num-floats) + (persistent! floats) + (recur (conj! floats (mem/read-float floats-slice (unchecked-multiply-int index mem/float-size))) + (unchecked-inc-int index)))) + (finally + (free-variable-length-array* floats-addr)))))] + (t/is (not (zero? @freed?))) + (t/is (= floats (mapv #(* (float 1.5) %) (range (count floats)))))))