-
Notifications
You must be signed in to change notification settings - Fork 0
/
ffi.hs
145 lines (112 loc) · 3.12 KB
/
ffi.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
------------------------------------------------------------------------------
--
-- Core.FFI
--
------------------------------------------------------------------------------
module Core.FFI (
reference,
apply0,
apply1,
apply2,
apply3,
apply4,
apply5,
apply6,
CBool,
ToC(..),
FromC(..),
) where
import Core
import Core.IO
import Foreign.C
import Foreign.Ptr
import Foreign.ForeignPtr
type CBool = CChar
------------------------------------------------------------------------------
-- Reference counted foreign pointers
------------------------------------------------------------------------------
foreign import ccall unsafe "&mrtRelease" mrtRelease :: FunPtr (Ptr a -> IO ())
reference :: Ptr a -> IO (ForeignPtr a)
reference x = newForeignPtr mrtRelease x
------------------------------------------------------------------------------
-- ToC
------------------------------------------------------------------------------
class ToC a b where
toC :: a -> (b -> IO c) -> IO c
instance ToC Bool CBool where
toC False f = f 0
toC True f = f 1
instance ToC Int CInt where
toC x f = f $ fromIntegral x
instance ToC Float CFloat where
toC x f = f $ CFloat x
instance ToC Double CDouble where
toC x f = f $ CDouble x
instance ToC [Char] CString where
toC = withCString
instance ToC [Char] CWString where
toC = withCWString
instance ToC (ForeignPtr a) (Ptr a) where
toC = withForeignPtr
------------------------------------------------------------------------------
-- FromC
------------------------------------------------------------------------------
class FromC a b where
fromC :: IO a -> IO b
instance FromC () () where
fromC = id
instance FromC CBool Bool where
fromC iox = do
x <- iox
return (x /= 0)
instance FromC CInt Int where
fromC iox = map fromIntegral iox
instance FromC CFloat Float where
fromC iox = do
x <- iox
return $ realToFrac x
instance FromC CDouble Double where
fromC iox = do
x <- iox
return $ realToFrac x
instance FromC (Ptr a) (ForeignPtr a) where
fromC px = px >>= reference
instance FromC (Ptr a) (Maybe (ForeignPtr a)) where
fromC px = do
p <- px
if p == nullPtr then return None else Some <$> reference p
------------------------------------------------------------------------------
-- ApplyC
------------------------------------------------------------------------------
apply0 x = fromC x
apply1 f x0 = toC x0 $ \p0 -> fromC $ f p0
apply2 f x0 x1 =
toC x0 $ \p0 ->
toC x1 $ \p1 ->
fromC $ f p0 p1
apply3 f x0 x1 x2 =
toC x0 $ \p0 ->
toC x1 $ \p1 ->
toC x2 $ \p2 ->
fromC $ f p0 p1 p2
apply4 f x0 x1 x2 x3 =
toC x0 $ \p0 ->
toC x1 $ \p1 ->
toC x2 $ \p2 ->
toC x3 $ \p3 ->
fromC $ f p0 p1 p2 p3
apply5 f x0 x1 x2 x3 x4 =
toC x0 $ \p0 ->
toC x1 $ \p1 ->
toC x2 $ \p2 ->
toC x3 $ \p3 ->
toC x4 $ \p4 ->
fromC $ f p0 p1 p2 p3 p4
apply6 f x0 x1 x2 x3 x4 x5 =
toC x0 $ \p0 ->
toC x1 $ \p1 ->
toC x2 $ \p2 ->
toC x3 $ \p3 ->
toC x4 $ \p4 ->
toC x5 $ \p5 ->
fromC $ f p0 p1 p2 p3 p4 p5