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