From 95856cb4f3279567339f78160b340735c3d53b19 Mon Sep 17 00:00:00 2001 From: Joshua Suskalo Date: Mon, 10 Jan 2022 13:31:27 -0600 Subject: [PATCH] Add with-c-layout function --- src/clj/coffi/layout.clj | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/clj/coffi/layout.clj diff --git a/src/clj/coffi/layout.clj b/src/clj/coffi/layout.clj new file mode 100644 index 0000000..d92e02d --- /dev/null +++ b/src/clj/coffi/layout.clj @@ -0,0 +1,29 @@ +(ns coffi.layout + "Functions for adjusting the layout of structs." + (:require + [coffi.mem :as mem])) + +(defn with-c-layout + "Forces a struct specification to C layout rules. + + This will add padding fields between fields to match C alignment + requirements." + [struct-spec] + (let [aligned-fields + (loop [offset 0 + aligned-fields [] + fields (nth struct-spec 1)] + (if (seq fields) + (let [[[_ type :as field] & fields] fields + size (mem/size-of type) + r (rem offset (mem/align-of type))] + (recur (+ offset r size) + (cond-> aligned-fields + (pos? r) (conj [:padding [::mem/padding r]]) + :always (conj field)) + fields)) + (let [strongest-alignment (mem/align-of struct-spec) + r (rem offset strongest-alignment)] + (cond-> aligned-fields + (pos? r) (conj [:padding [::mem/padding r]])))))] + (assoc struct-spec 1 aligned-fields)))