@@ -3,7 +3,6 @@
33module CFFI.Types
44
55import Data.Vect
6−import Data.HVect
76
87%access public export
98%default partial
@@ -11,6 +10,7 @@ import Data.HVect
1110||| An universe of C types.
1211data CType = I8 | I16 | I32 | I64 | FLOAT | DOUBLE | PTR
1312
13+||| Composites of C types
1414data Composite = T CType | ARRAY Int Composite | STRUCT (List Composite) | UNION (List Composite)
1515 | PACKEDSTRUCT (List Composite)
1616
@@ -42,95 +42,87 @@ translate FLOAT = Double
4242translate DOUBLE = Double
4343translate PTR = Ptr
4444
45−translateComp : Composite -> Type
46−translateComp (T ct) = translate ct
47−translateComp (ARRAY n t) = Vect (toNat n) (translateComp t)
48−translateComp (STRUCT xs) = HVect $ fromList (map translateComp xs)
49−translateComp (UNION xs) = HVect $ fromList (map translateComp xs)
50−translateComp (PACKEDSTRUCT xs) = HVect $ fromList (map translateComp xs)
51−
5245mutual
53− sizeOf : CType -> Int
54− sizeOf I8 = 1
55− sizeOf I16 = 2
56− sizeOf I32 = 4
57− sizeOf I64 = 8
58− sizeOf FLOAT = 4
59− sizeOf DOUBLE = 8
60− sizeOf PTR = prim__sizeofPtr
61−
62− sizeOfComp : Composite -> Int
63− sizeOfComp (T ct) = sizeOf ct
64− sizeOfComp (ARRAY n t) = n * sizeOfComp t
65− sizeOfComp (STRUCT xs) = sizeOfStruct xs
66− sizeOfComp (UNION xs) = foldl (\acc, x =>max acc $ sizeOfComp x) 0 xs
67− sizeOfComp (PACKEDSTRUCT xs) = foldl (\acc, x => acc + sizeOfComp x) 0 xs
68−
69− alignOf : CType -> Int
70− alignOf I8 = 1
71− alignOf I16 = 2
72− alignOf I32 = 4
73− alignOf I64 = prim__sizeofPtr
74− alignOf FLOAT = 4
75− alignOf DOUBLE = prim__sizeofPtr
76− alignOf PTR = prim__sizeofPtr
77−
78− alignOfComp : Composite -> Int
79− alignOfComp (T t) = alignOf t
80− alignOfComp (ARRAY n t) = alignOfComp t
81− alignOfComp (STRUCT xs) = foldl (\acc, x => max acc $ alignOfComp x) 0 xs
82− alignOfComp (UNION xs) = foldl (\acc, x => max acc $ alignOfComp x) 0 xs
83− alignOfComp (PACKEDSTRUCT xs) = 1
46+ sizeOfCT : CType -> Int
47+ sizeOfCT I8 = 1
48+ sizeOfCT I16 = 2
49+ sizeOfCT I32 = 4
50+ sizeOfCT I64 = 8
51+ sizeOfCT FLOAT = 4
52+ sizeOfCT DOUBLE = 8
53+ sizeOfCT PTR = prim__sizeofPtr
54+
55+ sizeOf : Composite -> Int
56+ sizeOf (T ct) = sizeOfCT ct
57+ sizeOf (ARRAY n t) = n * sizeOf t
58+ sizeOf (STRUCT xs) = sizeOfStruct xs
59+ sizeOf (UNION xs) = foldl (\acc, x =>max acc $ sizeOf x) 0 xs
60+ sizeOf (PACKEDSTRUCT xs) = foldl (\acc, x => acc + sizeOf x) 0 xs
61+
62+ alignOfCT : CType -> Int
63+ alignOfCT I8 = 1
64+ alignOfCT I16 = 2
65+ alignOfCT I32 = 4
66+ alignOfCT I64 = prim__sizeofPtr
67+ alignOfCT FLOAT = 4
68+ alignOfCT DOUBLE = prim__sizeofPtr
69+ alignOfCT PTR = prim__sizeofPtr
70+
71+ alignOf : Composite -> Int
72+ alignOf (T t) = alignOfCT t
73+ alignOf (ARRAY n t) = alignOf t
74+ alignOf (STRUCT xs) = foldl (\acc, x => max acc $ alignOf x) 0 xs
75+ alignOf (UNION xs) = foldl (\acc, x => max acc $ alignOf x) 0 xs
76+ alignOf (PACKEDSTRUCT xs) = 1
77+
78+ pad : Int -> Int -> Int
79+ pad pos align = let c = pos `mod` align in if c == 0 then 0 else align - c
80+
81+ nextOffset : Composite -> Int -> Int
82+ nextOffset ty pos = pos + pad pos (alignOf ty)
8483
8584 offsetsStruct : List Composite -> List Int
86− offsetsStruct xs = offsets' xs [] 0
85+ offsetsStruct xs = offsets' xs 0
8786 where
88− offsets' : List Composite -> List Int -> Int -> List Int
89− offsets' [] acc _ = reverse acc
90− offsets' (x::xs) ys curr = let a = alignOfComp x
91− padding = let c = curr `mod` a
92− in if c == 0 then 0 else a - c
93− off = curr + padding
94− in offsets' xs (off::ys) (off + sizeOfComp x)
87+ offsets' : List Composite -> Int -> List Int
88+ offsets' [] _ = []
89+ offsets' (x::xs) pos = (nextOffset x pos)::(offsets' xs (nextOffset x pos + sizeOf x))
9590
9691 sizeOfStruct : List Composite -> Int
97− sizeOfStruct xs = case (reverse xs, reverse (offsetsStruct xs)) of
98− ([], _) => 0
99− (x::_, y::_) => let end = y + sizeOfComp x
100− endPadding = let c = end `mod` align in
101− if c == 0 then 0 else align - c
102− in end + endPadding
92+ sizeOfStruct xs = sizeStruct' xs 0 1
10393 where
104− align : Int
105− align = foldl (\acc, x => max acc $ alignOfComp x) 1 xs
94+ sizeStruct' : List Composite -> Int -> Int -> Int
95+ sizeStruct' [] pos maxAlign = pos + (pad pos maxAlign)
96+ sizeStruct' (x::xs) pos maxAlign = sizeStruct' xs (nextOffset x pos + sizeOf x)
97+ (max maxAlign (alignOf x))
10698
10799fields : Composite -> Nat
108100fields (STRUCT xs) = length xs
109101fields (PACKEDSTRUCT xs) = length xs
110102fields (UNION xs) = length xs
111103fields (ARRAY n _) = toNat n
112−fields _ = 1
104+fields (T _) = 1
113105
114106offsetsPacked : List Composite -> List Int
115107offsetsPacked xs = offsets' xs [] 0
116108 where
117109 offsets' : List Composite -> List Int -> Int -> List Int
118110 offsets' [] acc _ = reverse acc
119− offsets' (x::xs) acc pos = offsets' xs (pos::acc) (sizeOfComp x)
111+ offsets' (x::xs) acc pos = offsets' xs (pos::acc) (sizeOf x)
120112
121113-- TODO: Use index and fix upp proofs.
122114offset : Composite -> Nat -> Int
123115offset (STRUCT xs) i = fromMaybe 0 $ index' i (offsetsStruct xs)
124116offset (PACKEDSTRUCT xs) i = fromMaybe 0 $ index' i (offsetsPacked xs)
125−offset (ARRAY _ t) i = sizeOfComp t * toIntNat i
126−offset _ _ = 0
117+offset (ARRAY _ t) i = sizeOf t * toIntNat i
118+offset (T _) _ = 0
127119
128120offsets : Composite -> List Int
129121offsets (STRUCT xs) = offsetsStruct xs
130122offsets (PACKEDSTRUCT xs) = offsetsPacked xs
131123offsets (UNION xs) = replicate (length xs) 0
132−offsets (ARRAY n t) = [ x*sizeOfComp t | x <- [0..n-1]]
133−offsets _ = [0]
124+offsets (ARRAY n t) = [ x*sizeOf t | x <- [0..n-1]]
125+offsets (T _) = [0]
134126
135127-- TODO: handle out of bounds with proofs
136128-- Also choose a better name.