X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FStable.lhs;h=0de033d1c639a19ed0bb3975a8f17bc7da86e604;hb=d98bd1c893b597a0748dc863b70ee186b5991186;hp=80af1f22c40b66be7f56aba2d28392666ad23369;hpb=b706340c451952adf230b5b8daecad8a1f34d714;p=ghc-base.git diff --git a/GHC/Stable.lhs b/GHC/Stable.lhs index 80af1f2..0de033d 100644 --- a/GHC/Stable.lhs +++ b/GHC/Stable.lhs @@ -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)