[project @ 2005-03-05 15:13:01 by panne]
[ghc-base.git] / GHC / Stable.lhs
index 80af1f2..0de033d 100644 (file)
@@ -1,9 +1,9 @@
 \begin{code}
-{-# OPTIONS -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -fno-implicit-prelude #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  GHC.Stable
--- Copyright   :  (c) The University of Glasgow, 1992-2002
+-- Copyright   :  (c) The University of Glasgow, 1992-2004
 -- License     :  see libraries/base/LICENSE
 -- 
 -- Maintainer  :  ffi@haskell.org
@@ -14,6 +14,7 @@
 --
 -----------------------------------------------------------------------------
 
+-- #hide
 module GHC.Stable 
        ( StablePtr(..)
        , newStablePtr          -- :: a -> IO (StablePtr a)    
@@ -30,23 +31,70 @@ import GHC.IOBase
 -----------------------------------------------------------------------------
 -- Stable Pointers
 
-data StablePtr a = StablePtr (StablePtr# a)
+{- |
+A /stable pointer/ is a reference to a Haskell expression that is
+guaranteed not to be affected by garbage collection, i.e., it will neither be
+deallocated nor will the value of the stable pointer itself change during
+garbage collection (ordinary references may be relocated during garbage
+collection).  Consequently, stable pointers can be passed to foreign code,
+which can treat it as an opaque reference to a Haskell value.
 
-instance CCallable   (StablePtr a)
-instance CReturnable (StablePtr a)
+A value of type @StablePtr a@ is a stable pointer to a Haskell
+expression of type @a@.
+-}
+data StablePtr a = StablePtr (StablePtr# a)
 
+-- |
+-- Create a stable pointer referring to the given Haskell value.
+--
 newStablePtr   :: a -> IO (StablePtr a)
 newStablePtr a = IO $ \ s ->
     case makeStablePtr# a s of (# s', sp #) -> (# s', StablePtr sp #)
 
+-- |
+-- Obtain the Haskell value referenced by a stable pointer, i.e., the
+-- same value that was passed to the corresponding call to
+-- 'makeStablePtr'.  If the argument to 'deRefStablePtr' has
+-- already been freed using 'freeStablePtr', the behaviour of
+-- 'deRefStablePtr' is undefined.
+--
 deRefStablePtr :: StablePtr a -> IO a
 deRefStablePtr (StablePtr sp) = IO $ \s -> deRefStablePtr# sp s
 
-foreign import ccall unsafe freeStablePtr :: StablePtr a -> IO ()
+-- |
+-- Dissolve the association between the stable pointer and the Haskell
+-- value. Afterwards, if the stable pointer is passed to
+-- 'deRefStablePtr' or 'freeStablePtr', the behaviour is
+-- undefined.  However, the stable pointer may still be passed to
+-- 'castStablePtrToPtr', but the @'Foreign.Ptr.Ptr' ()@ value returned
+-- by 'castStablePtrToPtr', in this case, is undefined (in particular,
+-- it may be 'Foreign.Ptr.nullPtr').  Nevertheless, the call
+-- to 'castStablePtrToPtr' is guaranteed not to diverge.
+--
+foreign import ccall unsafe "hs_free_stable_ptr" freeStablePtr :: StablePtr a -> IO ()
 
+-- |
+-- Coerce a stable pointer to an address. No guarantees are made about
+-- the resulting value, except that the original stable pointer can be
+-- recovered by 'castPtrToStablePtr'.  In particular, the address may not
+-- refer to an accessible memory location and any attempt to pass it to
+-- the member functions of the class 'Foreign.Storable.Storable' leads to
+-- undefined behaviour.
+--
 castStablePtrToPtr :: StablePtr a -> Ptr ()
 castStablePtrToPtr (StablePtr s) = Ptr (unsafeCoerce# s)
 
+
+-- |
+-- The inverse of 'castStablePtrToPtr', i.e., we have the identity
+-- 
+-- > sp == castPtrToStablePtr (castStablePtrToPtr sp)
+-- 
+-- for any stable pointer @sp@ on which 'freeStablePtr' has
+-- not been executed yet.  Moreover, 'castPtrToStablePtr' may
+-- only be applied to pointers that have been produced by
+-- 'castStablePtrToPtr'.
+--
 castPtrToStablePtr :: Ptr () -> StablePtr a
 castPtrToStablePtr (Ptr a) = StablePtr (unsafeCoerce# a)