blob: b92bfd9b645d7101e3f02fbd26f702935b3aa25b (
plain)
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
|
-- | Foreign export stubs
{-# LANGUAGE DerivingVia #-}
module GHC.Types.ForeignStubs
( ForeignStubs (..)
, CHeader(..)
, CStub(..)
, initializerCStub
, finalizerCStub
, appendStubC
)
where
import {-# SOURCE #-} GHC.Cmm.CLabel
import GHC.Platform
import GHC.Utils.Outputable
import Data.List ((++))
import Data.Monoid
import Data.Semigroup
import Data.Coerce
data CStub = CStub { getCStub :: SDoc
, getInitializers :: [CLabel]
-- ^ Initializers to be run at startup
-- See Note [Initializers and finalizers in Cmm] in
-- "GHC.Cmm.InitFini".
, getFinalizers :: [CLabel]
-- ^ Finalizers to be run at shutdown
}
emptyCStub :: CStub
emptyCStub = CStub empty [] []
instance Monoid CStub where
mempty = emptyCStub
instance Semigroup CStub where
CStub a0 b0 c0 <> CStub a1 b1 c1 =
CStub (a0 $$ a1) (b0 ++ b1) (c0 ++ c1)
functionCStub :: Platform -> CLabel -> SDoc -> SDoc -> CStub
functionCStub platform clbl declarations body =
CStub body' [] []
where
body' = vcat
[ declarations
, hsep [text "void", pprCLabel platform CStyle clbl, text "(void)"]
, braces body
]
-- | @initializerCStub fn_nm decls body@ is a 'CStub' containing C initializer
-- function (e.g. an entry of the @.init_array@ section) named
-- @fn_nm@ with the given body and the given set of declarations.
initializerCStub :: Platform -> CLabel -> SDoc -> SDoc -> CStub
initializerCStub platform clbl declarations body =
functionCStub platform clbl declarations body
`mappend` CStub empty [clbl] []
-- | @finalizerCStub fn_nm decls body@ is a 'CStub' containing C finalizer
-- function (e.g. an entry of the @.fini_array@ section) named
-- @fn_nm@ with the given body and the given set of declarations.
finalizerCStub :: Platform -> CLabel -> SDoc -> SDoc -> CStub
finalizerCStub platform clbl declarations body =
functionCStub platform clbl declarations body
`mappend` CStub empty [] [clbl]
newtype CHeader = CHeader { getCHeader :: SDoc }
instance Monoid CHeader where
mempty = CHeader empty
mconcat = coerce vcat
instance Semigroup CHeader where
(<>) = coerce ($$)
-- | Foreign export stubs
data ForeignStubs
= NoStubs
-- ^ We don't have any stubs
| ForeignStubs CHeader CStub
-- ^ There are some stubs. Parameters:
--
-- 1) Header file prototypes for
-- "foreign exported" functions
--
-- 2) C stubs to use when calling
-- "foreign exported" functions
appendStubC :: ForeignStubs -> CStub -> ForeignStubs
appendStubC NoStubs c_code = ForeignStubs mempty c_code
appendStubC (ForeignStubs h c) c_code = ForeignStubs h (c `mappend` c_code)
|