base: Manually unlit .lhs into .hs modules
[ghc.git] / libraries / base / GHC / Stable.hs
1 {-# LANGUAGE Unsafe, DeriveDataTypeable #-}
2 {-# LANGUAGE NoImplicitPrelude
3 , MagicHash
4 , UnboxedTuples
5 #-}
6 {-# OPTIONS_HADDOCK hide #-}
7
8 -----------------------------------------------------------------------------
9 -- |
10 -- Module : GHC.Stable
11 -- Copyright : (c) The University of Glasgow, 1992-2004
12 -- License : see libraries/base/LICENSE
13 --
14 -- Maintainer : ffi@haskell.org
15 -- Stability : internal
16 -- Portability : non-portable (GHC Extensions)
17 --
18 -- Stable pointers.
19 --
20 -----------------------------------------------------------------------------
21
22 module GHC.Stable (
23 StablePtr(..),
24 newStablePtr,
25 deRefStablePtr,
26 freeStablePtr,
27 castStablePtrToPtr,
28 castPtrToStablePtr
29 ) where
30
31 import GHC.Ptr
32 import GHC.Base
33 import Data.Typeable.Internal
34
35 -----------------------------------------------------------------------------
36 -- Stable Pointers
37
38 {- |
39 A /stable pointer/ is a reference to a Haskell expression that is
40 guaranteed not to be affected by garbage collection, i.e., it will neither be
41 deallocated nor will the value of the stable pointer itself change during
42 garbage collection (ordinary references may be relocated during garbage
43 collection). Consequently, stable pointers can be passed to foreign code,
44 which can treat it as an opaque reference to a Haskell value.
45
46 A value of type @StablePtr a@ is a stable pointer to a Haskell
47 expression of type @a@.
48 -}
49 data {-# CTYPE "HsStablePtr" #-} StablePtr a = StablePtr (StablePtr# a)
50 deriving( Typeable )
51
52 -- |
53 -- Create a stable pointer referring to the given Haskell value.
54 --
55 newStablePtr :: a -> IO (StablePtr a)
56 newStablePtr a = IO $ \ s ->
57 case makeStablePtr# a s of (# s', sp #) -> (# s', StablePtr sp #)
58
59 -- |
60 -- Obtain the Haskell value referenced by a stable pointer, i.e., the
61 -- same value that was passed to the corresponding call to
62 -- 'makeStablePtr'. If the argument to 'deRefStablePtr' has
63 -- already been freed using 'freeStablePtr', the behaviour of
64 -- 'deRefStablePtr' is undefined.
65 --
66 deRefStablePtr :: StablePtr a -> IO a
67 deRefStablePtr (StablePtr sp) = IO $ \s -> deRefStablePtr# sp s
68
69 -- |
70 -- Dissolve the association between the stable pointer and the Haskell
71 -- value. Afterwards, if the stable pointer is passed to
72 -- 'deRefStablePtr' or 'freeStablePtr', the behaviour is
73 -- undefined. However, the stable pointer may still be passed to
74 -- 'castStablePtrToPtr', but the @'Foreign.Ptr.Ptr' ()@ value returned
75 -- by 'castStablePtrToPtr', in this case, is undefined (in particular,
76 -- it may be 'Foreign.Ptr.nullPtr'). Nevertheless, the call
77 -- to 'castStablePtrToPtr' is guaranteed not to diverge.
78 --
79 foreign import ccall unsafe "hs_free_stable_ptr" freeStablePtr :: StablePtr a -> IO ()
80
81 -- |
82 -- Coerce a stable pointer to an address. No guarantees are made about
83 -- the resulting value, except that the original stable pointer can be
84 -- recovered by 'castPtrToStablePtr'. In particular, the address may not
85 -- refer to an accessible memory location and any attempt to pass it to
86 -- the member functions of the class 'Foreign.Storable.Storable' leads to
87 -- undefined behaviour.
88 --
89 castStablePtrToPtr :: StablePtr a -> Ptr ()
90 castStablePtrToPtr (StablePtr s) = Ptr (unsafeCoerce# s)
91
92
93 -- |
94 -- The inverse of 'castStablePtrToPtr', i.e., we have the identity
95 --
96 -- > sp == castPtrToStablePtr (castStablePtrToPtr sp)
97 --
98 -- for any stable pointer @sp@ on which 'freeStablePtr' has
99 -- not been executed yet. Moreover, 'castPtrToStablePtr' may
100 -- only be applied to pointers that have been produced by
101 -- 'castStablePtrToPtr'.
102 --
103 castPtrToStablePtr :: Ptr () -> StablePtr a
104 castPtrToStablePtr (Ptr a) = StablePtr (unsafeCoerce# a)
105
106 instance Eq (StablePtr a) where
107 (StablePtr sp1) == (StablePtr sp2) =
108 case eqStablePtr# sp1 sp2 of
109 0# -> False
110 _ -> True