X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FStable.lhs;h=e96bf687ae909bf1dbf0071581edcf72cfb7e786;hb=41e8fba828acbae1751628af50849f5352b27873;hp=9a55a6871b98f9396be1291729e47ca089e430d6;hpb=c37cf4507dd8093addd6ef6a91fd7046f2f1f2fb;p=ghc-base.git diff --git a/GHC/Stable.lhs b/GHC/Stable.lhs index 9a55a68..e96bf68 100644 --- a/GHC/Stable.lhs +++ b/GHC/Stable.lhs @@ -1,9 +1,15 @@ \begin{code} -{-# OPTIONS -fno-implicit-prelude #-} +{-# LANGUAGE NoImplicitPrelude + , MagicHash + , UnboxedTuples + , ForeignFunctionInterface + #-} +{-# OPTIONS_HADDOCK hide #-} + ----------------------------------------------------------------------------- -- | -- 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,42 +20,93 @@ -- ----------------------------------------------------------------------------- +-- #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 +{- | +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. + +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}