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