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