X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FForeignPtr.hs;h=dbf6c2c180597ed260f7710205d286be3a3ff1fa;hb=be2750a0a11b919fb03cc070074e430f88bdfa90;hp=9868942d7639b83f7c6b65d9cc52e4926804e57d;hpb=18ddadf0b8e35084a51f2560c3fe24ca8a2f3fea;p=ghc-base.git diff --git a/GHC/ForeignPtr.hs b/GHC/ForeignPtr.hs index 9868942..dbf6c2c 100644 --- a/GHC/ForeignPtr.hs +++ b/GHC/ForeignPtr.hs @@ -1,5 +1,12 @@ -{-# OPTIONS_GHC -XNoImplicitPrelude #-} +{-# LANGUAGE CPP + , NoImplicitPrelude + , BangPatterns + , MagicHash + , UnboxedTuples + #-} {-# OPTIONS_HADDOCK hide #-} +{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-} + ----------------------------------------------------------------------------- -- | -- Module : GHC.ForeignPtr @@ -42,7 +49,7 @@ import Data.Typeable import GHC.Show import GHC.List ( null ) import GHC.Base -import GHC.IOBase +import GHC.IORef import GHC.STRef ( STRef(..) ) import GHC.Ptr ( Ptr(..), FunPtr(..) ) import GHC.Err @@ -99,7 +106,7 @@ instance Show (ForeignPtr a) where showsPrec p f = showsPrec p (unsafeForeignPtrToPtr f) --- |A Finalizer is represented as a pointer to a foreign function that, at +-- |A finalizer is represented as a pointer to a foreign function that, at -- finalisation time, gets as an argument a plain pointer variant of the -- foreign pointer that the finalizer is associated with. -- @@ -149,19 +156,23 @@ mallocForeignPtr :: Storable a => IO (ForeignPtr a) -- mallocForeignPtr = doMalloc undefined where doMalloc :: Storable b => b -> IO (ForeignPtr b) - doMalloc a = do + doMalloc a + | I# size < 0 = error "mallocForeignPtr: size must be >= 0" + | otherwise = do r <- newIORef (NoFinalizers, []) IO $ \s -> case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) -> (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#)) (MallocPtr mbarr# r) #) } - where (I# size) = sizeOf a - (I# align) = alignment a + where !(I# size) = sizeOf a + !(I# align) = alignment a -- | This function is similar to 'mallocForeignPtr', except that the -- size of the memory required is given explicitly as a number of bytes. mallocForeignPtrBytes :: Int -> IO (ForeignPtr a) +mallocForeignPtrBytes size | size < 0 = + error "mallocForeignPtrBytes: size must be >= 0" mallocForeignPtrBytes (I# size) = do r <- newIORef (NoFinalizers, []) IO $ \s -> @@ -186,19 +197,23 @@ mallocForeignPtrBytes (I# size) = do mallocPlainForeignPtr :: Storable a => IO (ForeignPtr a) mallocPlainForeignPtr = doMalloc undefined where doMalloc :: Storable b => b -> IO (ForeignPtr b) - doMalloc a = IO $ \s -> + doMalloc a + | I# size < 0 = error "mallocForeignPtr: size must be >= 0" + | otherwise = IO $ \s -> case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) -> (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#)) (PlainPtr mbarr#) #) } - where (I# size) = sizeOf a - (I# align) = alignment a + where !(I# size) = sizeOf a + !(I# align) = alignment a -- | This function is similar to 'mallocForeignPtrBytes', except that -- the internally an optimised ForeignPtr representation with no -- finalizer is used. Attempts to add a finalizer will cause an -- exception to be thrown. mallocPlainForeignPtrBytes :: Int -> IO (ForeignPtr a) +mallocPlainForeignPtrBytes size | size < 0 = + error "mallocPlainForeignPtrBytes: size must be >= 0" mallocPlainForeignPtrBytes (I# size) = IO $ \s -> case newPinnedByteArray# size s of { (# s', mbarr# #) -> (# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#)) @@ -213,7 +228,7 @@ addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of PlainForeignPtr r -> f r >> return () MallocPtr _ r -> f r >> return () _ -> error "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" - where + where f r = noMixing CFinalizers r $ IO $ \s -> @@ -223,7 +238,7 @@ addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of addForeignPtrFinalizerEnv :: FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO () --- ^ like 'addForeignPtrFinalizerEnv' but allows the finalizer to be +-- ^ Like 'addForeignPtrFinalizerEnv' but allows the finalizer to be -- passed an additional environment parameter to be passed to the -- finalizer. The environment passed to the finalizer is fixed by the -- second argument to 'addForeignPtrFinalizerEnv' @@ -231,7 +246,7 @@ addForeignPtrFinalizerEnv (FunPtr fp) (Ptr ep) (ForeignPtr p c) = case c of PlainForeignPtr r -> f r >> return () MallocPtr _ r -> f r >> return () _ -> error "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" - where + where f r = noMixing CFinalizers r $ IO $ \s -> @@ -348,7 +363,7 @@ unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a -- To avoid subtle coding errors, hand written marshalling code -- should preferably use 'Foreign.ForeignPtr.withForeignPtr' rather -- than combinations of 'unsafeForeignPtrToPtr' and --- 'touchForeignPtr'. However, the later routines +-- 'touchForeignPtr'. However, the latter routines -- are occasionally preferred in tool generated marshalling code. unsafeForeignPtrToPtr (ForeignPtr fo _) = Ptr fo