X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FStable.lhs;h=b52e756053914a677f6a15eac102a0331a7b2bfd;hb=696a935b0818ab9cf1a4fbd93faf9add88ead1cd;hp=691fe6c52f971dd15e37d0ad9e809f71f254f06a;hpb=7f1f4e7a695c402ddd3a1dc2cc7114e649a78ebc;p=ghc-base.git diff --git a/GHC/Stable.lhs b/GHC/Stable.lhs index 691fe6c..b52e756 100644 --- a/GHC/Stable.lhs +++ b/GHC/Stable.lhs @@ -1,13 +1,18 @@ -% ----------------------------------------------------------------------------- -% $Id: Stable.lhs,v 1.1 2001/06/28 14:15:03 simonmar Exp $ -% -% (c) The GHC Team, 1992-2000 -% - -\section{Module @GHC.Stable@} - \begin{code} -{-# OPTIONS -fno-implicit-prelude #-} +{-# OPTIONS_GHC -fno-implicit-prelude #-} +----------------------------------------------------------------------------- +-- | +-- 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. +-- +----------------------------------------------------------------------------- module GHC.Stable ( StablePtr(..) @@ -18,31 +23,77 @@ module GHC.Stable , castPtrToStablePtr -- :: Ptr () -> StablePtr a ) where -import Foreign.Ptr - +import GHC.Ptr import GHC.Base 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 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 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)