X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FStable.lhs;h=e96bf687ae909bf1dbf0071581edcf72cfb7e786;hb=f98950484a7cb01e43352e3d88277a2784cd58bf;hp=b7c0d654a811b6cdaaa8c253067fcdb23ca28f52;hpb=92c8414dd1b8771e9e1d1ab4cde694669edf4be5;p=ghc-base.git diff --git a/GHC/Stable.lhs b/GHC/Stable.lhs index b7c0d65..e96bf68 100644 --- a/GHC/Stable.lhs +++ b/GHC/Stable.lhs @@ -1,53 +1,112 @@ -% ----------------------------------------------------------------------------- -% $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}