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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
%
% (c) The AQUA Project, Glasgow University, 1994-1998
%
\section[TysPrim]{Wired-in knowledge about primitive types}
This module tracks the ``state interface'' document, ``GHC prelude:
types and operations.''
\begin{code}
module TysPrim(
alphaTyVars, betaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
alphaTy, betaTy, gammaTy, deltaTy,
openAlphaTyVar, openAlphaTyVars,
charPrimTyCon, charPrimTy,
intPrimTyCon, intPrimTy,
wordPrimTyCon, wordPrimTy,
addrPrimTyCon, addrPrimTy,
floatPrimTyCon, floatPrimTy,
doublePrimTyCon, doublePrimTy,
statePrimTyCon, mkStatePrimTy,
realWorldTyCon, realWorldTy, realWorldStatePrimTy,
arrayPrimTyCon, mkArrayPrimTy,
byteArrayPrimTyCon, byteArrayPrimTy,
mutableArrayPrimTyCon, mkMutableArrayPrimTy,
mutableByteArrayPrimTyCon, mkMutableByteArrayPrimTy,
mutVarPrimTyCon, mkMutVarPrimTy,
mVarPrimTyCon, mkMVarPrimTy,
stablePtrPrimTyCon, mkStablePtrPrimTy,
stableNamePrimTyCon, mkStableNamePrimTy,
weakPrimTyCon, mkWeakPrimTy,
foreignObjPrimTyCon, foreignObjPrimTy,
threadIdPrimTyCon, threadIdPrimTy,
int64PrimTyCon, int64PrimTy,
word64PrimTyCon, word64PrimTy,
primRepTyCon,
pcPrimTyCon
) where
#include "HsVersions.h"
import Var ( TyVar, mkSysTyVar )
import Name ( mkWiredInTyConName )
import PrimRep ( PrimRep(..), isFollowableRep )
import TyCon ( mkPrimTyCon, TyCon, ArgVrcs )
import Type ( Type,
mkTyConApp, mkTyConTy, mkTyVarTys,
unboxedTypeKind, boxedTypeKind, openTypeKind, mkArrowKinds
)
import PrelMods ( pREL_GHC )
import Outputable
import Unique
\end{code}
\begin{code}
alphaTyVars :: [TyVar]
alphaTyVars = [ mkSysTyVar u boxedTypeKind
| u <- map mkAlphaTyVarUnique [2..] ]
betaTyVars = tail alphaTyVars
alphaTyVar, betaTyVar, gammaTyVar :: TyVar
(alphaTyVar:betaTyVar:gammaTyVar:deltaTyVar:_) = alphaTyVars
alphaTys = mkTyVarTys alphaTyVars
(alphaTy:betaTy:gammaTy:deltaTy:_) = alphaTys
-- openAlphaTyVar is prepared to be instantiated
-- to a boxed or unboxed type variable. It's used for the
-- result type for "error", so that we can have (error Int# "Help")
openAlphaTyVar :: TyVar
openAlphaTyVar = mkSysTyVar (mkAlphaTyVarUnique 1) openTypeKind
openAlphaTyVars :: [TyVar]
openAlphaTyVars = [ mkSysTyVar u openTypeKind
| u <- map mkAlphaTyVarUnique [2..] ]
vrcPos,vrcZero :: (Bool,Bool)
vrcPos = (True,False)
vrcZero = (False,False)
vrcsP,vrcsZ,vrcsZP :: ArgVrcs
vrcsP = [vrcPos]
vrcsZ = [vrcZero]
vrcsZP = [vrcZero,vrcPos]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-basic]{Basic primitive types (@Char#@, @Int#@, etc.)}
%* *
%************************************************************************
\begin{code}
-- only used herein
pcPrimTyCon :: Unique{-TyConKey-} -> FAST_STRING -> Int -> ArgVrcs -> PrimRep -> TyCon
pcPrimTyCon key str arity arg_vrcs rep
= the_tycon
where
name = mkWiredInTyConName key pREL_GHC str the_tycon
the_tycon = mkPrimTyCon name kind arity arg_vrcs rep
kind = mkArrowKinds (take arity (repeat boxedTypeKind)) result_kind
result_kind | isFollowableRep rep = boxedTypeKind -- Represented by a GC-ish ptr
| otherwise = unboxedTypeKind -- Represented by a non-ptr
charPrimTy = mkTyConTy charPrimTyCon
charPrimTyCon = pcPrimTyCon charPrimTyConKey SLIT("Char#") 0 [] CharRep
intPrimTy = mkTyConTy intPrimTyCon
intPrimTyCon = pcPrimTyCon intPrimTyConKey SLIT("Int#") 0 [] IntRep
int64PrimTy = mkTyConTy int64PrimTyCon
int64PrimTyCon = pcPrimTyCon int64PrimTyConKey SLIT("Int64#") 0 [] Int64Rep
wordPrimTy = mkTyConTy wordPrimTyCon
wordPrimTyCon = pcPrimTyCon wordPrimTyConKey SLIT("Word#") 0 [] WordRep
word64PrimTy = mkTyConTy word64PrimTyCon
word64PrimTyCon = pcPrimTyCon word64PrimTyConKey SLIT("Word64#") 0 [] Word64Rep
addrPrimTy = mkTyConTy addrPrimTyCon
addrPrimTyCon = pcPrimTyCon addrPrimTyConKey SLIT("Addr#") 0 [] AddrRep
floatPrimTy = mkTyConTy floatPrimTyCon
floatPrimTyCon = pcPrimTyCon floatPrimTyConKey SLIT("Float#") 0 [] FloatRep
doublePrimTy = mkTyConTy doublePrimTyCon
doublePrimTyCon = pcPrimTyCon doublePrimTyConKey SLIT("Double#") 0 [] DoubleRep
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-state]{The @State#@ type (and @_RealWorld@ types)}
%* *
%************************************************************************
State# is the primitive, unboxed type of states. It has one type parameter,
thus
State# RealWorld
or
State# s
where s is a type variable. The only purpose of the type parameter is to
keep different state threads separate. It is represented by nothing at all.
\begin{code}
mkStatePrimTy ty = mkTyConApp statePrimTyCon [ty]
statePrimTyCon = pcPrimTyCon statePrimTyConKey SLIT("State#") 1 vrcsZ VoidRep
\end{code}
@_RealWorld@ is deeply magical. It {\em is primitive}, but it
{\em is not unboxed} (hence PtrRep).
We never manipulate values of type RealWorld; it's only used in the type
system, to parameterise State#.
\begin{code}
realWorldTy = mkTyConTy realWorldTyCon
realWorldTyCon = pcPrimTyCon realWorldTyConKey SLIT("RealWorld") 0 [] PtrRep
realWorldStatePrimTy = mkStatePrimTy realWorldTy -- State# RealWorld
\end{code}
Note: the ``state-pairing'' types are not truly primitive, so they are
defined in \tr{TysWiredIn.lhs}, not here.
%************************************************************************
%* *
\subsection[TysPrim-arrays]{The primitive array types}
%* *
%************************************************************************
\begin{code}
arrayPrimTyCon = pcPrimTyCon arrayPrimTyConKey SLIT("Array#") 1 vrcsP ArrayRep
byteArrayPrimTyCon = pcPrimTyCon byteArrayPrimTyConKey SLIT("ByteArray#") 0 [] ByteArrayRep
mutableArrayPrimTyCon = pcPrimTyCon mutableArrayPrimTyConKey SLIT("MutableArray#")
2 vrcsZP ArrayRep
mutableByteArrayPrimTyCon = pcPrimTyCon mutableByteArrayPrimTyConKey SLIT("MutableByteArray#")
1 vrcsZ ByteArrayRep
mkArrayPrimTy elt = mkTyConApp arrayPrimTyCon [elt]
byteArrayPrimTy = mkTyConTy byteArrayPrimTyCon
mkMutableArrayPrimTy s elt = mkTyConApp mutableArrayPrimTyCon [s, elt]
mkMutableByteArrayPrimTy s = mkTyConApp mutableByteArrayPrimTyCon [s]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-mut-var]{The mutable variable type}
%* *
%************************************************************************
\begin{code}
mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConKey SLIT("MutVar#")
2 vrcsZP PtrRep
mkMutVarPrimTy s elt = mkTyConApp mutVarPrimTyCon [s, elt]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-synch-var]{The synchronizing variable type}
%* *
%************************************************************************
\begin{code}
mVarPrimTyCon = pcPrimTyCon mVarPrimTyConKey SLIT("MVar#")
2 vrcsZP PtrRep
mkMVarPrimTy s elt = mkTyConApp mVarPrimTyCon [s, elt]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-stable-ptrs]{The stable-pointer type}
%* *
%************************************************************************
\begin{code}
stablePtrPrimTyCon = pcPrimTyCon stablePtrPrimTyConKey SLIT("StablePtr#")
1 vrcsP StablePtrRep
mkStablePtrPrimTy ty = mkTyConApp stablePtrPrimTyCon [ty]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-stable-names]{The stable-name type}
%* *
%************************************************************************
\begin{code}
stableNamePrimTyCon = pcPrimTyCon stableNamePrimTyConKey SLIT("StableName#")
1 vrcsP StableNameRep
mkStableNamePrimTy ty = mkTyConApp stableNamePrimTyCon [ty]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-foreign-objs]{The ``foreign object'' type}
%* *
%************************************************************************
A Foreign Object is just a boxed, unlifted, Addr#. They're needed
because finalisers (weak pointers) can't watch Addr#s, they can only
watch heap-resident objects.
We can't use a lifted Addr# (such as Addr) because race conditions
could bite us. For example, if the program deconstructed the Addr
before passing its contents to a ccall, and a weak pointer was
watching the Addr, the weak pointer might deduce that the Addr was
dead before it really was.
\begin{code}
foreignObjPrimTy = mkTyConTy foreignObjPrimTyCon
foreignObjPrimTyCon = pcPrimTyCon foreignObjPrimTyConKey SLIT("ForeignObj#") 0 [] ForeignObjRep
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-Weak]{The ``weak pointer'' type}
%* *
%************************************************************************
\begin{code}
weakPrimTyCon = pcPrimTyCon weakPrimTyConKey SLIT("Weak#") 1 vrcsP WeakPtrRep
mkWeakPrimTy v = mkTyConApp weakPrimTyCon [v]
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-thread-ids]{The ``thread id'' type}
%* *
%************************************************************************
A thread id is represented by a pointer to the TSO itself, to ensure
that they are always unique and we can always find the TSO for a given
thread id. However, this has the unfortunate consequence that a
ThreadId# for a given thread is treated as a root by the garbage
collector and can keep TSOs around for too long.
Hence the programmer API for thread manipulation uses a weak pointer
to the thread id internally.
\begin{code}
threadIdPrimTy = mkTyConTy threadIdPrimTyCon
threadIdPrimTyCon = pcPrimTyCon threadIdPrimTyConKey SLIT("ThreadId#") 0 [] ThreadIdRep
\end{code}
%************************************************************************
%* *
\subsection[TysPrim-PrimRep]{Making types from PrimReps}
%* *
%************************************************************************
Each of the primitive types from this module is equivalent to a
PrimRep (see PrimRep.lhs). The following function returns the
primitive TyCon for a given PrimRep.
\begin{code}
primRepTyCon CharRep = charPrimTyCon
primRepTyCon IntRep = intPrimTyCon
primRepTyCon WordRep = wordPrimTyCon
primRepTyCon Int64Rep = int64PrimTyCon
primRepTyCon Word64Rep = word64PrimTyCon
primRepTyCon AddrRep = addrPrimTyCon
primRepTyCon FloatRep = floatPrimTyCon
primRepTyCon DoubleRep = doublePrimTyCon
primRepTyCon StablePtrRep = stablePtrPrimTyCon
primRepTyCon ForeignObjRep = foreignObjPrimTyCon
primRepTyCon WeakPtrRep = weakPrimTyCon
primRepTyCon other = pprPanic "primRepTyCon" (ppr other)
\end{code}
|