2 % (c) The AQUA Project, Glasgow University, 1994-1998
4 \section[TysPrim]{Wired-in knowledge about primitive types}
6 This module tracks the ``state interface'' document, ``GHC prelude:
7 types and operations.''
11 alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
12 alphaTy, betaTy, gammaTy, deltaTy,
13 openAlphaTyVar, openAlphaTyVars,
15 charPrimTyCon, charPrimTy,
16 intPrimTyCon, intPrimTy,
17 wordPrimTyCon, wordPrimTy,
18 addrPrimTyCon, addrPrimTy,
19 floatPrimTyCon, floatPrimTy,
20 doublePrimTyCon, doublePrimTy,
22 statePrimTyCon, mkStatePrimTy,
23 realWorldTyCon, realWorldTy, realWorldStatePrimTy,
25 arrayPrimTyCon, mkArrayPrimTy,
26 byteArrayPrimTyCon, byteArrayPrimTy,
27 mutableArrayPrimTyCon, mkMutableArrayPrimTy,
28 mutableByteArrayPrimTyCon, mkMutableByteArrayPrimTy,
29 mutVarPrimTyCon, mkMutVarPrimTy,
31 mVarPrimTyCon, mkMVarPrimTy,
32 stablePtrPrimTyCon, mkStablePtrPrimTy,
33 weakPrimTyCon, mkWeakPrimTy,
34 foreignObjPrimTyCon, foreignObjPrimTy,
35 threadIdPrimTyCon, threadIdPrimTy,
37 int64PrimTyCon, int64PrimTy,
38 word64PrimTyCon, word64PrimTy,
45 #include "HsVersions.h"
47 import Var ( TyVar, mkSysTyVar )
48 import Name ( mkWiredInTyConName )
49 import PrimRep ( PrimRep(..), isFollowableRep )
50 import TyCon ( mkPrimTyCon, TyCon )
52 mkTyConApp, mkTyConTy, mkTyVarTys,
53 unboxedTypeKind, boxedTypeKind, openTypeKind, mkArrowKinds
55 import PrelMods ( pREL_GHC )
61 alphaTyVars :: [TyVar]
62 alphaTyVars = [ mkSysTyVar u boxedTypeKind
63 | u <- map mkAlphaTyVarUnique [2..] ]
65 alphaTyVar, betaTyVar, gammaTyVar :: TyVar
66 (alphaTyVar:betaTyVar:gammaTyVar:deltaTyVar:_) = alphaTyVars
68 alphaTys = mkTyVarTys alphaTyVars
69 (alphaTy:betaTy:gammaTy:deltaTy:_) = alphaTys
71 -- openAlphaTyVar is prepared to be instantiated
72 -- to a boxed or unboxed type variable. It's used for the
73 -- result type for "error", so that we can have (error Int# "Help")
74 openAlphaTyVar :: TyVar
75 openAlphaTyVar = mkSysTyVar (mkAlphaTyVarUnique 1) openTypeKind
77 openAlphaTyVars :: [TyVar]
78 openAlphaTyVars = [ mkSysTyVar u openTypeKind
79 | u <- map mkAlphaTyVarUnique [2..] ]
82 %************************************************************************
84 \subsection[TysPrim-basic]{Basic primitive types (@Char#@, @Int#@, etc.)}
86 %************************************************************************
90 pcPrimTyCon :: Unique{-TyConKey-} -> FAST_STRING -> Int -> PrimRep -> TyCon
91 pcPrimTyCon key str arity rep
94 name = mkWiredInTyConName key pREL_GHC str the_tycon
95 the_tycon = mkPrimTyCon name kind arity rep
96 kind = mkArrowKinds (take arity (repeat openTypeKind)) result_kind
97 result_kind | isFollowableRep rep = boxedTypeKind -- Represented by a GC-ish ptr
98 | otherwise = unboxedTypeKind -- Represented by a non-ptr
100 charPrimTy = mkTyConTy charPrimTyCon
101 charPrimTyCon = pcPrimTyCon charPrimTyConKey SLIT("Char#") 0 CharRep
103 intPrimTy = mkTyConTy intPrimTyCon
104 intPrimTyCon = pcPrimTyCon intPrimTyConKey SLIT("Int#") 0 IntRep
106 int64PrimTy = mkTyConTy int64PrimTyCon
107 int64PrimTyCon = pcPrimTyCon int64PrimTyConKey SLIT("Int64#") 0 Int64Rep
109 wordPrimTy = mkTyConTy wordPrimTyCon
110 wordPrimTyCon = pcPrimTyCon wordPrimTyConKey SLIT("Word#") 0 WordRep
112 word64PrimTy = mkTyConTy word64PrimTyCon
113 word64PrimTyCon = pcPrimTyCon word64PrimTyConKey SLIT("Word64#") 0 Word64Rep
115 addrPrimTy = mkTyConTy addrPrimTyCon
116 addrPrimTyCon = pcPrimTyCon addrPrimTyConKey SLIT("Addr#") 0 AddrRep
118 floatPrimTy = mkTyConTy floatPrimTyCon
119 floatPrimTyCon = pcPrimTyCon floatPrimTyConKey SLIT("Float#") 0 FloatRep
121 doublePrimTy = mkTyConTy doublePrimTyCon
122 doublePrimTyCon = pcPrimTyCon doublePrimTyConKey SLIT("Double#") 0 DoubleRep
126 %************************************************************************
128 \subsection[TysPrim-state]{The @State#@ type (and @_RealWorld@ types)}
130 %************************************************************************
132 State# is the primitive, unboxed type of states. It has one type parameter,
138 where s is a type variable. The only purpose of the type parameter is to
139 keep different state threads separate. It is represented by nothing at all.
142 mkStatePrimTy ty = mkTyConApp statePrimTyCon [ty]
143 statePrimTyCon = pcPrimTyCon statePrimTyConKey SLIT("State#") 1 VoidRep
146 @_RealWorld@ is deeply magical. It {\em is primitive}, but it
147 {\em is not unboxed} (hence PtrRep).
148 We never manipulate values of type RealWorld; it's only used in the type
149 system, to parameterise State#.
152 realWorldTy = mkTyConTy realWorldTyCon
153 realWorldTyCon = pcPrimTyCon realWorldTyConKey SLIT("RealWorld") 0 PtrRep
154 realWorldStatePrimTy = mkStatePrimTy realWorldTy
157 Note: the ``state-pairing'' types are not truly primitive, so they are
158 defined in \tr{TysWiredIn.lhs}, not here.
161 %************************************************************************
163 \subsection[TysPrim-arrays]{The primitive array types}
165 %************************************************************************
168 arrayPrimTyCon = pcPrimTyCon arrayPrimTyConKey SLIT("Array#") 1 ArrayRep
170 byteArrayPrimTyCon = pcPrimTyCon byteArrayPrimTyConKey SLIT("ByteArray#") 0 ByteArrayRep
172 mutableArrayPrimTyCon = pcPrimTyCon mutableArrayPrimTyConKey SLIT("MutableArray#") 2 ArrayRep
174 mutableByteArrayPrimTyCon = pcPrimTyCon mutableByteArrayPrimTyConKey SLIT("MutableByteArray#") 1 ByteArrayRep
176 mkArrayPrimTy elt = mkTyConApp arrayPrimTyCon [elt]
177 byteArrayPrimTy = mkTyConTy byteArrayPrimTyCon
178 mkMutableArrayPrimTy s elt = mkTyConApp mutableArrayPrimTyCon [s, elt]
179 mkMutableByteArrayPrimTy s = mkTyConApp mutableByteArrayPrimTyCon [s]
182 %************************************************************************
184 \subsection[TysPrim-mut-var]{The mutable variable type}
186 %************************************************************************
189 mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConKey SLIT("MutVar#") 2 PtrRep
191 mkMutVarPrimTy s elt = mkTyConApp mutVarPrimTyCon [s, elt]
194 %************************************************************************
196 \subsection[TysPrim-synch-var]{The synchronizing variable type}
198 %************************************************************************
201 mVarPrimTyCon = pcPrimTyCon mVarPrimTyConKey SLIT("MVar#") 2 PtrRep
203 mkMVarPrimTy s elt = mkTyConApp mVarPrimTyCon [s, elt]
206 %************************************************************************
208 \subsection[TysPrim-stable-ptrs]{The stable-pointer type}
210 %************************************************************************
213 stablePtrPrimTyCon = pcPrimTyCon stablePtrPrimTyConKey SLIT("StablePtr#") 1 StablePtrRep
215 mkStablePtrPrimTy ty = mkTyConApp stablePtrPrimTyCon [ty]
218 %************************************************************************
220 \subsection[TysPrim-foreign-objs]{The ``foreign object'' type}
222 %************************************************************************
224 A Foreign Object is just a boxed, unlifted, Addr#. They're needed
225 because finalisers (weak pointers) can't watch Addr#s, they can only
226 watch heap-resident objects.
228 We can't use a lifted Addr# (such as Addr) because race conditions
229 could bite us. For example, if the program deconstructed the Addr
230 before passing its contents to a ccall, and a weak pointer was
231 watching the Addr, the weak pointer might deduce that the Addr was
232 dead before it really was.
235 foreignObjPrimTy = mkTyConTy foreignObjPrimTyCon
236 foreignObjPrimTyCon = pcPrimTyCon foreignObjPrimTyConKey SLIT("ForeignObj#") 0 ForeignObjRep
239 %************************************************************************
241 \subsection[TysPrim-Weak]{The ``weak pointer'' type}
243 %************************************************************************
246 weakPrimTyCon = pcPrimTyCon weakPrimTyConKey SLIT("Weak#") 1 WeakPtrRep
248 mkWeakPrimTy v = mkTyConApp weakPrimTyCon [v]
251 %************************************************************************
253 \subsection[TysPrim-thread-ids]{The ``thread id'' type}
255 %************************************************************************
257 A thread id is represented by a pointer to the TSO itself, to ensure
258 that they are always unique and we can always find the TSO for a given
259 thread id. However, this has the unfortunate consequence that a
260 ThreadId# for a given thread is treated as a root by the garbage
261 collector and can keep TSOs around for too long.
263 Hence the programmer API for thread manipulation uses a weak pointer
264 to the thread id internally.
267 threadIdPrimTy = mkTyConTy threadIdPrimTyCon
268 threadIdPrimTyCon = pcPrimTyCon threadIdPrimTyConKey SLIT("ThreadId#") 0 ThreadIdRep
271 %************************************************************************
273 \subsection[TysPrim-PrimRep]{Making types from PrimReps}
275 %************************************************************************
277 Each of the primitive types from this module is equivalent to a
278 PrimRep (see PrimRep.lhs). The following function returns the
279 primitive TyCon for a given PrimRep.
282 primRepTyCon CharRep = charPrimTyCon
283 primRepTyCon IntRep = intPrimTyCon
284 primRepTyCon WordRep = wordPrimTyCon
285 primRepTyCon Int64Rep = int64PrimTyCon
286 primRepTyCon Word64Rep = word64PrimTyCon
287 primRepTyCon AddrRep = addrPrimTyCon
288 primRepTyCon FloatRep = floatPrimTyCon
289 primRepTyCon DoubleRep = doublePrimTyCon
290 primRepTyCon StablePtrRep = stablePtrPrimTyCon
291 primRepTyCon ForeignObjRep = foreignObjPrimTyCon
292 primRepTyCon WeakPtrRep = weakPrimTyCon
293 primRepTyCon other = pprPanic "primRepTyCon" (ppr other)