final revision to GArrow classes
[ghc-base.git] / GHC / Stable.lhs
index b7c0d65..e96bf68 100644 (file)
-% -----------------------------------------------------------------------------
-% $Id: Stable.lhs,v 1.3 2002/04/24 15:47:34 simonmar Exp $
-%
-% (c) The GHC Team, 1992-2000
-%
-
-\section{Module @GHC.Stable@}
-
 \begin{code}
-{-# OPTIONS -fno-implicit-prelude #-}
+{-# LANGUAGE NoImplicitPrelude
+           , MagicHash
+           , UnboxedTuples
+           , ForeignFunctionInterface
+  #-}
+{-# OPTIONS_HADDOCK hide #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Stable
+-- Copyright   :  (c) The University of Glasgow, 1992-2004
+-- License     :  see libraries/base/LICENSE
+-- 
+-- Maintainer  :  ffi@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- Stable pointers.
+--
+-----------------------------------------------------------------------------
 
+-- #hide
 module GHC.Stable 
-       ( StablePtr(..)
-       , newStablePtr          -- :: a -> IO (StablePtr a)    
-       , deRefStablePtr        -- :: StablePtr a -> a
-       , freeStablePtr         -- :: StablePtr a -> IO ()
-       , castStablePtrToPtr    -- :: StablePtr a -> Ptr ()
-       , castPtrToStablePtr    -- :: Ptr () -> StablePtr a
+        ( StablePtr(..)
+        , newStablePtr          -- :: a -> IO (StablePtr a)    
+        , deRefStablePtr        -- :: StablePtr a -> a
+        , freeStablePtr         -- :: StablePtr a -> IO ()
+        , castStablePtrToPtr    -- :: StablePtr a -> Ptr ()
+        , castPtrToStablePtr    -- :: Ptr () -> StablePtr a
    ) where
 
 import GHC.Ptr
 import GHC.Base
-import GHC.IOBase
+-- import GHC.IO
 
 -----------------------------------------------------------------------------
 -- 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)
 
 instance Eq (StablePtr a) where 
     (StablePtr sp1) == (StablePtr sp2) =
-       case eqStablePtr# sp1 sp2 of
-          0# -> False
-          _  -> True
+        case eqStablePtr# sp1 sp2 of
+           0# -> False
+           _  -> True
 \end{code}