Add with-c-layout function

This commit is contained in:
Joshua Suskalo 2022-01-10 13:31:27 -06:00
parent 579393f830
commit 95856cb4f3

29
src/clj/coffi/layout.clj Normal file
View file

@ -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)))