    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE UnboxedTuples #-}
    {-# LANGUAGE Unsafe #-}

    {-# OPTIONS_HADDOCK not-home #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.ForeignPtr
    -- Copyright   :  (c) The University of Glasgow, 1992-2003
    -- License     :  see libraries/base/LICENSE
    --
    -- Maintainer  :  cvs-ghc@haskell.org
    -- Stability   :  internal
    -- Portability :  non-portable (GHC extensions)
    --
    -- GHC's implementation of the 'ForeignPtr' data type.
    --
    -----------------------------------------------------------------------------

    module GHC.ForeignPtr
      (
            -- * Types
            ForeignPtr(..),
            ForeignPtrContents(..),
            Finalizers(..),
            FinalizerPtr,
            FinalizerEnvPtr,
            -- * Create
            newForeignPtr_,
            mallocForeignPtr,
            mallocPlainForeignPtr,
            mallocForeignPtrBytes,
            mallocPlainForeignPtrBytes,
            mallocForeignPtrAlignedBytes,
            mallocPlainForeignPtrAlignedBytes,
            newConcForeignPtr,
            -- * Add Finalizers
            addForeignPtrFinalizer,
            addForeignPtrFinalizerEnv,
            addForeignPtrConcFinalizer,
            -- * Conversion
            unsafeForeignPtrToPtr,
            castForeignPtr,
            plusForeignPtr,
            -- * Control over lifetype
            withForeignPtr,
            unsafeWithForeignPtr,
            touchForeignPtr,
            -- * Finalization
            finalizeForeignPtr
            -- * Commentary
            -- $commentary
      ) where

    import Foreign.Storable
    import Data.Foldable    ( sequence_ )

    import GHC.Show
    import GHC.Base
    import GHC.IORef
    import GHC.STRef        ( STRef(..) )
    import GHC.Ptr          ( Ptr(..), FunPtr(..) )

    import Unsafe.Coerce    ( unsafeCoerce )

    -- |The type 'ForeignPtr' represents references to objects that are
    -- maintained in a foreign language, i.e., that are not part of the
    -- data structures usually managed by the Haskell storage manager.
    -- The essential difference between 'ForeignPtr's and vanilla memory
    -- references of type @Ptr a@ is that the former may be associated
    -- with /finalizers/. A finalizer is a routine that is invoked when
    -- the Haskell storage manager detects that - within the Haskell heap
    -- and stack - there are no more references left that are pointing to
    -- the 'ForeignPtr'.  Typically, the finalizer will, then, invoke
    -- routines in the foreign language that free the resources bound by
    -- the foreign object.
    --
    -- The 'ForeignPtr' is parameterised in the same way as 'Ptr'.  The
    -- type argument of 'ForeignPtr' should normally be an instance of
    -- class 'Storable'.
    --
    data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
            -- The Addr# in the ForeignPtr object is intentionally stored
            -- separately from the finalizer. The primary aim of the
            -- representation is to make withForeignPtr efficient; in fact,
            -- withForeignPtr should be just as efficient as unpacking a
            -- Ptr, and multiple withForeignPtrs can share an unpacked
            -- ForeignPtr. As a secondary benefit, this representation
            -- allows pointers to subregions within the same overall block
            -- to share the same finalizer (see 'plusForeignPtr'). Note
            -- that touchForeignPtr only has to touch the ForeignPtrContents
            -- object, because that ensures that whatever the finalizer is
            -- attached to is kept alive.

    -- | Functions called when a 'ForeignPtr' is finalized. Note that
    -- C finalizers and Haskell finalizers cannot be mixed.
    data Finalizers
      = NoFinalizers
        -- ^ No finalizer. If there is no intent to add a finalizer at
        -- any point in the future, consider 'FinalPtr' or 'PlainPtr' instead
        -- since these perform fewer allocations.
      | CFinalizers (Weak# ())
        -- ^ Finalizers are all C functions.
      | HaskellFinalizers [IO ()]
        -- ^ Finalizers are all Haskell functions.

    -- | Controls finalization of a 'ForeignPtr', that is, what should happen
    -- if the 'ForeignPtr' becomes unreachable. Visually, these data constructors
    -- are appropriate in these scenarios:
    --
    -- >                           Memory backing pointer is
    -- >                            GC-Managed   Unmanaged
    -- > Finalizer functions are: +------------+-----------------+
    -- >                 Allowed  | MallocPtr  | PlainForeignPtr |
    -- >                          +------------+-----------------+
    -- >              Prohibited  | PlainPtr   | FinalPtr        |
    -- >                          +------------+-----------------+
    data ForeignPtrContents
      = PlainForeignPtr !(IORef Finalizers)
        -- ^ The pointer refers to unmanaged memory that was allocated by
        -- a foreign function (typically using @malloc@). The finalizer
        -- frequently calls the C function @free@ or some variant of it.
      | FinalPtr
        -- ^ The pointer refers to unmanaged memory that should not be freed when
        -- the 'ForeignPtr' becomes unreachable. Functions that add finalizers
        -- to a 'ForeignPtr' throw exceptions when the 'ForeignPtr' is backed by
        -- 'PlainPtr'Most commonly, this is used with @Addr#@ literals.
        -- See Note [Why FinalPtr].
        --
        -- @since 4.15
      | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers)
        -- ^ The pointer refers to a byte array.
        -- The 'MutableByteArray#' field means that the 'MutableByteArray#' is
        -- reachable (by GC) whenever the 'ForeignPtr' is reachable. When the
        -- 'ForeignPtr' becomes unreachable, the runtime\'s normal GC recovers
        -- the memory backing it. Here, the finalizer function intended to be used
        -- to @free()@ any ancillary *unmanaged* memory pointed to by the
        -- 'MutableByteArray#'. See the @zlib@ library for an example of this use.
        --
        -- 1. Invariant: The 'Addr#' in the parent 'ForeignPtr' is an interior
        --    pointer into this 'MutableByteArray#'.
        -- 2. Invariant: The 'MutableByteArray#' is pinned, so the 'Addr#' does not
        --    get invalidated by the GC moving the byte array.
        -- 3. Invariant: A 'MutableByteArray#' must not be associated with more than
        --    one set of finalizers. For example, this is sound:
        --
        --    > incrGood :: ForeignPtr Word8 -> ForeignPtr Word8
        --    > incrGood (ForeignPtr p (MallocPtr m f)) = ForeignPtr (plusPtr p 1) (MallocPtr m f)
        --
        --    But this is unsound:
        --
        --    > incrBad :: ForeignPtr Word8 -> IO (ForeignPtr Word8)
        --    > incrBad (ForeignPtr p (MallocPtr m _)) = do
        --    >   f <- newIORef NoFinalizers
        --    >   pure (ForeignPtr p (MallocPtr m f))
      | PlainPtr (MutableByteArray# RealWorld)
        -- ^ The pointer refers to a byte array. Finalization is not
        -- supported. This optimizes @MallocPtr@ by avoiding the allocation
        -- of a @MutVar#@ when it is known that no one will add finalizers to
        -- the @ForeignPtr@. Functions that add finalizers to a 'ForeignPtr'
        -- throw exceptions when the 'ForeignPtr' is backed by 'PlainPtr'.
        -- The invariants that apply to 'MallocPtr' apply to 'PlainPtr' as well.

    -- Note [Why FinalPtr]
    --
    -- FinalPtr exists as an optimization for foreign pointers created
    -- from Addr# literals. Most commonly, this happens in the bytestring
    -- library, where the combination of OverloadedStrings and a rewrite
    -- rule overloads String literals as ByteString literals. See the
    -- rule "ByteString packChars/packAddress" in
    -- bytestring:Data.ByteString.Internal. Prior to the
    -- introduction of FinalPtr, bytestring used PlainForeignPtr (in
    -- Data.ByteString.Internal.unsafePackAddress) to handle such literals.
    -- With O2 optimization, the resulting Core from a GHC patched with a
    -- known-key cstringLength# function but without FinalPtr looked like:
    --
    --   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
    --   stringOne1 = "hello beautiful world"#
    --   RHS size: {terms: 11, types: 17, coercions: 0, joins: 0/0}
    --   stringOne
    --     = case newMutVar# NoFinalizers realWorld# of
    --       { (# ipv_i7b6, ipv1_i7b7 #) ->
    --       PS stringOne1 (PlainForeignPtr ipv1_i7b7) 0# 21#
    --       }
    --
    -- After the introduction of FinalPtr, the bytestring library was modified
    -- so that the resulting Core was instead:
    --
    --   RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
    --   stringOne1 = "hello beautiful world"#
    --   RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0}
    --   stringOne = PS stringOne1 FinalPtr 0# 21#
    --
    -- This improves performance in three ways:
    --
    -- 1. More optimization opportunities. GHC is willing to inline the FinalPtr
    --    variant of stringOne into its use sites. This means the offset and length
    --    are eligible for case-of-known-literal. Previously, this never happened.
    -- 2. Smaller binaries. Setting up the thunk to call newMutVar# required
    --    machine instruction in the generated code. On x86_64, FinalPtr reduces
    --    the size of binaries by about 450 bytes per ByteString literal.
    -- 3. Smaller memory footprint. Previously, every ByteString literal resulted
    --    in the allocation of a MutVar# and a PlainForeignPtr data constructor.
    --    These both hang around until the ByteString goes out of scope. FinalPtr
    --    eliminates both of these sources of allocations. The MutVar# is not
    --    allocated because FinalPtr does not allow it, and the data constructor
    --    is not allocated because FinalPtr is a nullary data constructor.
    --
    -- For more discussion of FinalPtr, see GHC MR #2165 and bytestring PR #191.

    -- | @since 2.01
    instance Eq (ForeignPtr a) where
        ForeignPtr a
    p == :: ForeignPtr a -> ForeignPtr a -> Bool
    == ForeignPtr a
    q  =  ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    p Ptr a -> Ptr a -> Bool
    forall a. Eq a => a -> a -> Bool
    == ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    q

    -- | @since 2.01
    instance Ord (ForeignPtr a) where
        compare :: ForeignPtr a -> ForeignPtr a -> Ordering
    compare ForeignPtr a
    p ForeignPtr a
    q  =  Ptr a -> Ptr a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    p) (ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    q)

    -- | @since 2.01
    instance Show (ForeignPtr a) where
        showsPrec :: Int -> ForeignPtr a -> ShowS
    showsPrec Int
    p ForeignPtr a
    f = Int -> Ptr a -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    p (ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    f)

    -- |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.
    --
    -- Note that the foreign function /must/ use the @ccall@ calling convention.
    --
    type FinalizerPtr a        = FunPtr (Ptr a -> IO ())
    type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr a -> IO ())

    newConcForeignPtr :: Ptr a -> IO () -> IO (ForeignPtr a)
    --
    -- ^Turns a plain memory reference into a foreign object by
    -- associating a finalizer - given by the monadic operation - with the
    -- reference.  The storage manager will start the finalizer, in a
    -- separate thread, some time after the last reference to the
    -- @ForeignPtr@ is dropped.  There is no guarantee of promptness, and
    -- in fact there is no guarantee that the finalizer will eventually
    -- run at all.
    --
    -- Note that references from a finalizer do not necessarily prevent
    -- another object from being finalized.  If A's finalizer refers to B
    -- (perhaps using 'touchForeignPtr', then the only guarantee is that
    -- B's finalizer will never be started before A's.  If both A and B
    -- are unreachable, then both finalizers will start together.  See
    -- 'touchForeignPtr' for more on finalizer ordering.
    --
    newConcForeignPtr :: forall a. Ptr a -> IO () -> IO (ForeignPtr a)
    newConcForeignPtr Ptr a
    p IO ()
    finalizer
      = do ForeignPtr a
    fObj <- Ptr a -> IO (ForeignPtr a)
    forall a. Ptr a -> IO (ForeignPtr a)
    newForeignPtr_ Ptr a
    p
           ForeignPtr a -> IO () -> IO ()
    forall a. ForeignPtr a -> IO () -> IO ()
    addForeignPtrConcFinalizer ForeignPtr a
    fObj IO ()
    finalizer
           ForeignPtr a -> IO (ForeignPtr a)
    forall (m :: * -> *) a. Monad m => a -> m a
    return ForeignPtr a
    fObj

    mallocForeignPtr :: Storable a => IO (ForeignPtr a)
    -- ^ Allocate some memory and return a 'ForeignPtr' to it.  The memory
    -- will be released automatically when the 'ForeignPtr' is discarded.
    --
    -- 'mallocForeignPtr' is equivalent to
    --
    -- >    do { p <- malloc; newForeignPtr finalizerFree p }
    --
    -- although it may be implemented differently internally: you may not
    -- assume that the memory returned by 'mallocForeignPtr' has been
    -- allocated with 'Foreign.Marshal.Alloc.malloc'.
    --
    -- GHC notes: 'mallocForeignPtr' has a heavily optimised
    -- implementation in GHC.  It uses pinned memory in the garbage
    -- collected heap, so the 'ForeignPtr' does not require a finalizer to
    -- free the memory.  Use of 'mallocForeignPtr' and associated
    -- functions is strongly recommended in preference to
    -- 'Foreign.ForeignPtr.newForeignPtr' with a finalizer.
    --
    mallocForeignPtr :: forall a. Storable a => IO (ForeignPtr a)
    mallocForeignPtr = a -> IO (ForeignPtr a)
    forall b. Storable b => b -> IO (ForeignPtr b)
    doMalloc a
    forall a. HasCallStack => a
    undefined
      where doMalloc :: Storable b => b -> IO (ForeignPtr b)
            doMalloc :: forall b. Storable b => b -> IO (ForeignPtr b)
    doMalloc b
    a
              | Int# -> Int
    I# Int#
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 = String -> IO (ForeignPtr b)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocForeignPtr: size must be >= 0"
              | Bool
    otherwise = do
              IORef Finalizers
    r <- Finalizers -> IO (IORef Finalizers)
    forall a. a -> IO (IORef a)
    newIORef Finalizers
    NoFinalizers
              (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
    -> IO (ForeignPtr b)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
     -> IO (ForeignPtr b))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
    -> IO (ForeignPtr b)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
                case Int#
    -> Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d.
    Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newAlignedPinnedByteArray# Int#
    size Int#
    align State# RealWorld
    s of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
                 (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr b
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                                   (MutableByteArray# RealWorld
    -> IORef Finalizers -> ForeignPtrContents
    MallocPtr MutableByteArray# RealWorld
    mbarr# IORef Finalizers
    r) #)
                }
                where !(I# Int#
    size)  = b -> Int
    forall a. Storable a => a -> Int
    sizeOf b
    a
                      !(I# Int#
    align) = b -> Int
    forall a. Storable a => a -> Int
    alignment b
    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 :: forall a. Int -> IO (ForeignPtr a)
    mallocForeignPtrBytes Int
    size | Int
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 =
      String -> IO (ForeignPtr a)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocForeignPtrBytes: size must be >= 0"
    mallocForeignPtrBytes (I# Int#
    size) = do
      IORef Finalizers
    r <- Finalizers -> IO (IORef Finalizers)
    forall a. a -> IO (IORef a)
    newIORef Finalizers
    NoFinalizers
      (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
     -> IO (ForeignPtr a))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
         case Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newPinnedByteArray# Int#
    size State# RealWorld
    s      of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
           (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                             (MutableByteArray# RealWorld
    -> IORef Finalizers -> ForeignPtrContents
    MallocPtr MutableByteArray# RealWorld
    mbarr# IORef Finalizers
    r) #)
         }

    -- | This function is similar to 'mallocForeignPtrBytes', except that the
    -- size and alignment of the memory required is given explicitly as numbers of
    -- bytes.
    mallocForeignPtrAlignedBytes :: Int -> Int -> IO (ForeignPtr a)
    mallocForeignPtrAlignedBytes :: forall a. Int -> Int -> IO (ForeignPtr a)
    mallocForeignPtrAlignedBytes Int
    size Int
    _align | Int
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 =
      String -> IO (ForeignPtr a)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocForeignPtrAlignedBytes: size must be >= 0"
    mallocForeignPtrAlignedBytes (I# Int#
    size) (I# Int#
    align) = do
      IORef Finalizers
    r <- Finalizers -> IO (IORef Finalizers)
    forall a. a -> IO (IORef a)
    newIORef Finalizers
    NoFinalizers
      (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
     -> IO (ForeignPtr a))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
         case Int#
    -> Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d.
    Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newAlignedPinnedByteArray# Int#
    size Int#
    align State# RealWorld
    s of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
           (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                             (MutableByteArray# RealWorld
    -> IORef Finalizers -> ForeignPtrContents
    MallocPtr MutableByteArray# RealWorld
    mbarr# IORef Finalizers
    r) #)
         }

    -- | Allocate some memory and return a 'ForeignPtr' to it.  The memory
    -- will be released automatically when the 'ForeignPtr' is discarded.
    --
    -- GHC notes: 'mallocPlainForeignPtr' has a heavily optimised
    -- implementation in GHC.  It uses pinned memory in the garbage
    -- collected heap, as for mallocForeignPtr. Unlike mallocForeignPtr, a
    -- ForeignPtr created with mallocPlainForeignPtr carries no finalizers.
    -- It is not possible to add a finalizer to a ForeignPtr created with
    -- mallocPlainForeignPtr. This is useful for ForeignPtrs that will live
    -- only inside Haskell (such as those created for packed strings).
    -- Attempts to add a finalizer to a ForeignPtr created this way, or to
    -- finalize such a pointer, will throw an exception.
    --
    mallocPlainForeignPtr :: Storable a => IO (ForeignPtr a)
    mallocPlainForeignPtr :: forall a. Storable a => IO (ForeignPtr a)
    mallocPlainForeignPtr = a -> IO (ForeignPtr a)
    forall b. Storable b => b -> IO (ForeignPtr b)
    doMalloc a
    forall a. HasCallStack => a
    undefined
      where doMalloc :: Storable b => b -> IO (ForeignPtr b)
            doMalloc :: forall b. Storable b => b -> IO (ForeignPtr b)
    doMalloc b
    a
              | Int# -> Int
    I# Int#
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 = String -> IO (ForeignPtr b)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocForeignPtr: size must be >= 0"
              | Bool
    otherwise = (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
    -> IO (ForeignPtr b)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
     -> IO (ForeignPtr b))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr b #))
    -> IO (ForeignPtr b)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
                case Int#
    -> Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d.
    Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newAlignedPinnedByteArray# Int#
    size Int#
    align State# RealWorld
    s of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
                 (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr b
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                                   (MutableByteArray# RealWorld -> ForeignPtrContents
    PlainPtr MutableByteArray# RealWorld
    mbarr#) #)
                }
                where !(I# Int#
    size)  = b -> Int
    forall a. Storable a => a -> Int
    sizeOf b
    a
                      !(I# Int#
    align) = b -> Int
    forall a. Storable a => a -> Int
    alignment b
    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 :: forall a. Int -> IO (ForeignPtr a)
    mallocPlainForeignPtrBytes Int
    size | Int
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 =
      String -> IO (ForeignPtr a)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocPlainForeignPtrBytes: size must be >= 0"
    mallocPlainForeignPtrBytes (I# Int#
    size) = (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
     -> IO (ForeignPtr a))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
        case Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newPinnedByteArray# Int#
    size State# RealWorld
    s      of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
           (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                             (MutableByteArray# RealWorld -> ForeignPtrContents
    PlainPtr MutableByteArray# RealWorld
    mbarr#) #)
         }

    -- | This function is similar to 'mallocForeignPtrAlignedBytes', 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.
    mallocPlainForeignPtrAlignedBytes :: Int -> Int -> IO (ForeignPtr a)
    mallocPlainForeignPtrAlignedBytes :: forall a. Int -> Int -> IO (ForeignPtr a)
    mallocPlainForeignPtrAlignedBytes Int
    size Int
    _align | Int
    size Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 =
      String -> IO (ForeignPtr a)
    forall a. String -> a
    errorWithoutStackTrace String
    "mallocPlainForeignPtrAlignedBytes: size must be >= 0"
    mallocPlainForeignPtrAlignedBytes (I# Int#
    size) (I# Int#
    align) = (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
     -> IO (ForeignPtr a))
    -> (State# RealWorld -> (# State# RealWorld, ForeignPtr a #))
    -> IO (ForeignPtr a)
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
        case Int#
    -> Int#
    -> State# RealWorld
    -> (# State# RealWorld, MutableByteArray# RealWorld #)
    forall d.
    Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newAlignedPinnedByteArray# Int#
    size Int#
    align State# RealWorld
    s of { (# State# RealWorld
    s', MutableByteArray# RealWorld
    mbarr# #) ->
           (# State# RealWorld
    s', Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (MutableByteArray# RealWorld -> Addr#
    forall d. MutableByteArray# d -> Addr#
    mutableByteArrayContents# MutableByteArray# RealWorld
    mbarr#)
                             (MutableByteArray# RealWorld -> ForeignPtrContents
    PlainPtr MutableByteArray# RealWorld
    mbarr#) #)
         }

    addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
    -- ^ This function adds a finalizer to the given foreign object.  The
    -- finalizer will run /before/ all other finalizers for the same
    -- object which have already been registered.
    addForeignPtrFinalizer :: forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
    addForeignPtrFinalizer (FunPtr Addr#
    fp) (ForeignPtr Addr#
    p ForeignPtrContents
    c) = case ForeignPtrContents
    c of
      PlainForeignPtr IORef Finalizers
    r -> IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> () -> IO ()
    forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    0# Addr#
    nullAddr# Addr#
    p ()
      MallocPtr     MutableByteArray# RealWorld
    _ IORef Finalizers
    r -> IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> ForeignPtrContents -> IO ()
    forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    0# Addr#
    nullAddr# Addr#
    p ForeignPtrContents
    c
      ForeignPtrContents
    _ -> String -> IO ()
    forall a. String -> a
    errorWithoutStackTrace String
    "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"

    -- Note [MallocPtr finalizers] (#10904)
    --
    -- When we have C finalizers for a MallocPtr, the memory is
    -- heap-resident and would normally be recovered by the GC before the
    -- finalizers run.  To prevent the memory from being reused too early,
    -- we attach the MallocPtr constructor to the "value" field of the
    -- weak pointer when we call mkWeak# in ensureCFinalizerWeak below.
    -- The GC will keep this field alive until the finalizers have run.

    addForeignPtrFinalizerEnv ::
      FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
    -- ^ Like 'addForeignPtrFinalizer' but the finalizer is passed an additional
    -- environment parameter.
    addForeignPtrFinalizerEnv :: forall env a.
    FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a -> IO ()
    addForeignPtrFinalizerEnv (FunPtr Addr#
    fp) (Ptr Addr#
    ep) (ForeignPtr Addr#
    p ForeignPtrContents
    c) = case ForeignPtrContents
    c of
      PlainForeignPtr IORef Finalizers
    r -> IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> () -> IO ()
    forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    1# Addr#
    ep Addr#
    p ()
      MallocPtr     MutableByteArray# RealWorld
    _ IORef Finalizers
    r -> IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> ForeignPtrContents -> IO ()
    forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    1# Addr#
    ep Addr#
    p ForeignPtrContents
    c
      ForeignPtrContents
    _ -> String -> IO ()
    forall a. String -> a
    errorWithoutStackTrace String
    "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer"

    addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO ()
    -- ^This function adds a finalizer to the given @ForeignPtr@.  The
    -- finalizer will run /before/ all other finalizers for the same
    -- object which have already been registered.
    --
    -- This is a variant of @addForeignPtrFinalizer@, where the finalizer
    -- is an arbitrary @IO@ action.  When it is invoked, the finalizer
    -- will run in a new thread.
    --
    -- NB. Be very careful with these finalizers.  One common trap is that
    -- if a finalizer references another finalized value, it does not
    -- prevent that value from being finalized.  In particular, 'System.IO.Handle's
    -- are finalized objects, so a finalizer should not refer to a
    -- 'System.IO.Handle' (including 'System.IO.stdout', 'System.IO.stdin', or
    -- 'System.IO.stderr').
    --
    addForeignPtrConcFinalizer :: forall a. ForeignPtr a -> IO () -> IO ()
    addForeignPtrConcFinalizer (ForeignPtr Addr#
    _ ForeignPtrContents
    c) IO ()
    finalizer =
      ForeignPtrContents -> IO () -> IO ()
    addForeignPtrConcFinalizer_ ForeignPtrContents
    c IO ()
    finalizer

    addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
    addForeignPtrConcFinalizer_ :: ForeignPtrContents -> IO () -> IO ()
    addForeignPtrConcFinalizer_ (PlainForeignPtr IORef Finalizers
    r) IO ()
    finalizer = do
      Bool
    noFinalizers <- IORef Finalizers -> IO () -> IO Bool
    insertHaskellFinalizer IORef Finalizers
    r IO ()
    finalizer
      if Bool
    noFinalizers
         then (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
    -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
                  case IORef Finalizers
    r of { IORef (STRef MutVar# RealWorld Finalizers
    r#) ->
                  case MutVar# RealWorld Finalizers
    -> ()
    -> (State# RealWorld -> (# State# RealWorld, () #))
    -> State# RealWorld
    -> (# State# RealWorld, Weak# () #)
    mkWeak# MutVar# RealWorld Finalizers
    r# () (IO () -> State# RealWorld -> (# State# RealWorld, () #)
    forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO (IO () -> State# RealWorld -> (# State# RealWorld, () #))
    -> IO () -> State# RealWorld -> (# State# RealWorld, () #)
    forall a b. (a -> b) -> a -> b
    $ IORef Finalizers -> IO ()
    foreignPtrFinalizer IORef Finalizers
    r) State# RealWorld
    s of {
                    (# State# RealWorld
    s1, Weak# ()
    _ #) -> (# State# RealWorld
    s1, () #) }}
         else () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    addForeignPtrConcFinalizer_ f :: ForeignPtrContents
    f@(MallocPtr MutableByteArray# RealWorld
    fo IORef Finalizers
    r) IO ()
    finalizer = do
      Bool
    noFinalizers <- IORef Finalizers -> IO () -> IO Bool
    insertHaskellFinalizer IORef Finalizers
    r IO ()
    finalizer
      if Bool
    noFinalizers
         then  (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
    -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
                   case MutableByteArray# RealWorld
    -> ()
    -> (State# RealWorld -> (# State# RealWorld, () #))
    -> State# RealWorld
    -> (# State# RealWorld, Weak# () #)
    mkWeak# MutableByteArray# RealWorld
    fo () State# RealWorld -> (# State# RealWorld, () #)
    finalizer' State# RealWorld
    s of
                      (# State# RealWorld
    s1, Weak# ()
    _ #) -> (# State# RealWorld
    s1, () #)
         else () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      where
        finalizer' :: State# RealWorld -> (# State# RealWorld, () #)
        finalizer' :: State# RealWorld -> (# State# RealWorld, () #)
    finalizer' = IO () -> State# RealWorld -> (# State# RealWorld, () #)
    forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO (IORef Finalizers -> IO ()
    foreignPtrFinalizer IORef Finalizers
    r IO () -> IO () -> IO ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ForeignPtrContents -> IO ()
    touch ForeignPtrContents
    f)

    addForeignPtrConcFinalizer_ ForeignPtrContents
    _ IO ()
    _ =
      String -> IO ()
    forall a. String -> a
    errorWithoutStackTrace String
    "GHC.ForeignPtr: attempt to add a finalizer to plain pointer or a final pointer"

    insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
    insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool
    insertHaskellFinalizer IORef Finalizers
    r IO ()
    f = do
      !Bool
    wasEmpty <- IORef Finalizers -> (Finalizers -> (Finalizers, Bool)) -> IO Bool
    forall a b. IORef a -> (a -> (a, b)) -> IO b
    atomicModifyIORefP IORef Finalizers
    r ((Finalizers -> (Finalizers, Bool)) -> IO Bool)
    -> (Finalizers -> (Finalizers, Bool)) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Finalizers
    finalizers -> case Finalizers
    finalizers of
          Finalizers
    NoFinalizers -> ([IO ()] -> Finalizers
    HaskellFinalizers [IO ()
    f], Bool
    True)
          HaskellFinalizers [IO ()]
    fs -> ([IO ()] -> Finalizers
    HaskellFinalizers (IO ()
    fIO () -> [IO ()] -> [IO ()]
    forall a. a -> [a] -> [a]
    :[IO ()]
    fs), Bool
    False)
          Finalizers
    _ -> (Finalizers, Bool)
    forall a. a
    noMixingError
      Bool -> IO Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    wasEmpty

    -- | A box around Weak#, private to this module.
    data MyWeak = MyWeak (Weak# ())

    insertCFinalizer ::
      IORef Finalizers -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer :: forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    flag Addr#
    ep Addr#
    p value
    val = do
      MyWeak Weak# ()
    w <- IORef Finalizers -> value -> IO MyWeak
    forall value. IORef Finalizers -> value -> IO MyWeak
    ensureCFinalizerWeak IORef Finalizers
    r value
    val
      (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
    -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s -> case Addr#
    -> Addr#
    -> Int#
    -> Addr#
    -> Weak# ()
    -> State# RealWorld
    -> (# State# RealWorld, Int# #)
    forall b.
    Addr#
    -> Addr#
    -> Int#
    -> Addr#
    -> Weak# b
    -> State# RealWorld
    -> (# State# RealWorld, Int# #)
    addCFinalizerToWeak# Addr#
    fp Addr#
    p Int#
    flag Addr#
    ep Weak# ()
    w State# RealWorld
    s of
          (# State# RealWorld
    s1, Int#
    1# #) -> (# State# RealWorld
    s1, () #)

          -- Failed to add the finalizer because some other thread
          -- has finalized w by calling foreignPtrFinalizer. We retry now.
          -- This won't be an infinite loop because that thread must have
          -- replaced the content of r before calling finalizeWeak#.
          (# State# RealWorld
    s1, Int#
    _ #) -> IO () -> State# RealWorld -> (# State# RealWorld, () #)
    forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO (IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    forall value.
    IORef Finalizers
    -> Addr# -> Int# -> Addr# -> Addr# -> value -> IO ()
    insertCFinalizer IORef Finalizers
    r Addr#
    fp Int#
    flag Addr#
    ep Addr#
    p value
    val) State# RealWorld
    s1

    -- Read the weak reference from an IORef Finalizers, creating it if necessary.
    -- Throws an exception if HaskellFinalizers is encountered.
    ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak
    ensureCFinalizerWeak :: forall value. IORef Finalizers -> value -> IO MyWeak
    ensureCFinalizerWeak ref :: IORef Finalizers
    ref@(IORef (STRef MutVar# RealWorld Finalizers
    r#)) value
    value = do
      Finalizers
    fin <- IORef Finalizers -> IO Finalizers
    forall a. IORef a -> IO a
    readIORef IORef Finalizers
    ref
      case Finalizers
    fin of
          CFinalizers Weak# ()
    weak -> MyWeak -> IO MyWeak
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Weak# () -> MyWeak
    MyWeak Weak# ()
    weak)
          HaskellFinalizers{} -> IO MyWeak
    forall a. a
    noMixingError
          Finalizers
    NoFinalizers -> (State# RealWorld -> (# State# RealWorld, MyWeak #)) -> IO MyWeak
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, MyWeak #)) -> IO MyWeak)
    -> (State# RealWorld -> (# State# RealWorld, MyWeak #))
    -> IO MyWeak
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
              case MutVar# RealWorld Finalizers
    -> () -> State# RealWorld -> (# State# RealWorld, Weak# () #)
    mkWeakNoFinalizer# MutVar# RealWorld Finalizers
    r# (value -> ()
    forall a b. a -> b
    unsafeCoerce value
    value) State# RealWorld
    s of { (# State# RealWorld
    s1, Weak# ()
    w #) ->
                 -- See Note [MallocPtr finalizers] (#10904)
              case MutVar# RealWorld Finalizers
    -> (Finalizers -> (Finalizers, (MyWeak, Bool)))
    -> State# RealWorld
    -> (# State# RealWorld, Finalizers, (Finalizers, (MyWeak, Bool)) #)
    forall d a c.
    MutVar# d a -> (a -> c) -> State# d -> (# State# d, a, c #)
    atomicModifyMutVar2# MutVar# RealWorld Finalizers
    r# (Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
    update Weak# ()
    w) State# RealWorld
    s1 of
                  { (# State# RealWorld
    s2, Finalizers
    _, (Finalizers
    _, (MyWeak
    weak, Bool
    needKill )) #) ->
              if Bool
    needKill
                then case Weak# ()
    -> State# RealWorld
    -> (# State# RealWorld, Int#,
          State# RealWorld -> (# State# RealWorld, Any #) #)
    forall a b.
    Weak# a
    -> State# RealWorld
    -> (# State# RealWorld, Int#,
          State# RealWorld -> (# State# RealWorld, b #) #)
    finalizeWeak# Weak# ()
    w State# RealWorld
    s2 of { (# State# RealWorld
    s3, Int#
    _, State# RealWorld -> (# State# RealWorld, Any #)
    _ #) ->
                  (# State# RealWorld
    s3, MyWeak
    weak #) }
                else (# State# RealWorld
    s2, MyWeak
    weak #) }}
      where
          update :: Weak# () -> Finalizers -> (Finalizers, (MyWeak, Bool))
    update Weak# ()
    _ fin :: Finalizers
    fin@(CFinalizers Weak# ()
    w) = (Finalizers
    fin, (Weak# () -> MyWeak
    MyWeak Weak# ()
    w, Bool
    True))
          update Weak# ()
    w Finalizers
    NoFinalizers = (Weak# () -> Finalizers
    CFinalizers Weak# ()
    w, (Weak# () -> MyWeak
    MyWeak Weak# ()
    w, Bool
    False))
          update Weak# ()
    _ Finalizers
    _ = (Finalizers, (MyWeak, Bool))
    forall a. a
    noMixingError

    noMixingError :: a
    noMixingError :: forall a. a
    noMixingError = String -> a
    forall a. String -> a
    errorWithoutStackTrace (String -> a) -> String -> a
    forall a b. (a -> b) -> a -> b
    $
       String
    "GHC.ForeignPtr: attempt to mix Haskell and C finalizers " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
       String
    "in the same ForeignPtr"

    -- Swap out the finalizers with NoFinalizers and then run them.
    foreignPtrFinalizer :: IORef Finalizers -> IO ()
    foreignPtrFinalizer :: IORef Finalizers -> IO ()
    foreignPtrFinalizer IORef Finalizers
    r = do
      Finalizers
    fs <- IORef Finalizers -> Finalizers -> IO Finalizers
    forall a. IORef a -> a -> IO a
    atomicSwapIORef IORef Finalizers
    r Finalizers
    NoFinalizers
                 -- atomic, see #7170
      case Finalizers
    fs of
        Finalizers
    NoFinalizers -> () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        CFinalizers Weak# ()
    w -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
    -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s -> case Weak# ()
    -> State# RealWorld
    -> (# State# RealWorld, Int#,
          State# RealWorld -> (# State# RealWorld, () #) #)
    forall a b.
    Weak# a
    -> State# RealWorld
    -> (# State# RealWorld, Int#,
          State# RealWorld -> (# State# RealWorld, b #) #)
    finalizeWeak# Weak# ()
    w State# RealWorld
    s of
            (# State# RealWorld
    s1, Int#
    1#, State# RealWorld -> (# State# RealWorld, () #)
    f #) -> State# RealWorld -> (# State# RealWorld, () #)
    f State# RealWorld
    s1
            (# State# RealWorld
    s1, Int#
    _, State# RealWorld -> (# State# RealWorld, () #)
    _ #) -> (# State# RealWorld
    s1, () #)
        HaskellFinalizers [IO ()]
    actions -> [IO ()] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, Monad m) =>
    t (m a) -> m ()
    sequence_ [IO ()]
    actions

    newForeignPtr_ :: Ptr a -> IO (ForeignPtr a)
    -- ^Turns a plain memory reference into a foreign pointer that may be
    -- associated with finalizers by using 'addForeignPtrFinalizer'.
    newForeignPtr_ :: forall a. Ptr a -> IO (ForeignPtr a)
    newForeignPtr_ (Ptr Addr#
    obj) =  do
      IORef Finalizers
    r <- Finalizers -> IO (IORef Finalizers)
    forall a. a -> IO (IORef a)
    newIORef Finalizers
    NoFinalizers
      ForeignPtr a -> IO (ForeignPtr a)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Addr# -> ForeignPtrContents -> ForeignPtr a
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr Addr#
    obj (IORef Finalizers -> ForeignPtrContents
    PlainForeignPtr IORef Finalizers
    r))

    withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
    -- ^This is a way to look at the pointer living inside a
    -- foreign object.  This function takes a function which is
    -- applied to that pointer. The resulting 'IO' action is then
    -- executed. The foreign object is kept alive at least during
    -- the whole action, even if it is not used directly
    -- inside. Note that it is not safe to return the pointer from
    -- the action and use it after the action completes. All uses
    -- of the pointer should be inside the
    -- 'withForeignPtr' bracket.  The reason for
    -- this unsafeness is the same as for
    -- 'unsafeForeignPtrToPtr' below: the finalizer
    -- may run earlier than expected, because the compiler can only
    -- track usage of the 'ForeignPtr' object, not
    -- a 'Ptr' object made from it.
    --
    -- This function is normally used for marshalling data to
    -- or from the object pointed to by the
    -- 'ForeignPtr', using the operations from the
    -- 'Storable' class.
    withForeignPtr :: forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr fo :: ForeignPtr a
    fo@(ForeignPtr Addr#
    _ ForeignPtrContents
    r) Ptr a -> IO b
    f = (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, b #)) -> IO b)
    -> (State# RealWorld -> (# State# RealWorld, b #)) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s ->
      case Ptr a -> IO b
    f (ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    fo) of
        IO State# RealWorld -> (# State# RealWorld, b #)
    action# -> ForeignPtrContents
    -> State# RealWorld
    -> (State# RealWorld -> (# State# RealWorld, b #))
    -> (# State# RealWorld, b #)
    keepAlive# ForeignPtrContents
    r State# RealWorld
    s State# RealWorld -> (# State# RealWorld, b #)
    action#

    -- | This is similar to 'withForeignPtr' but comes with an important caveat:
    -- the user must guarantee that the continuation does not diverge (e.g. loop or
    -- throw an exception). In exchange for this loss of generality, this function
    -- offers the ability of GHC to optimise more aggressively.
    --
    -- Specifically, applications of the form:
    -- @
    -- unsafeWithForeignPtr fptr ('Control.Monad.forever' something)
    -- @
    --
    -- See GHC issue #17760 for more information about the unsoundness behavior
    -- that this function can result in.
    unsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
    unsafeWithForeignPtr :: forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    unsafeWithForeignPtr ForeignPtr a
    fo Ptr a -> IO b
    f = do
      b
    r <- Ptr a -> IO b
    f (ForeignPtr a -> Ptr a
    forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr ForeignPtr a
    fo)
      ForeignPtr a -> IO ()
    forall a. ForeignPtr a -> IO ()
    touchForeignPtr ForeignPtr a
    fo
      b -> IO b
    forall (m :: * -> *) a. Monad m => a -> m a
    return b
    r

    touchForeignPtr :: ForeignPtr a -> IO ()
    -- ^This function ensures that the foreign object in
    -- question is alive at the given place in the sequence of IO
    -- actions. However, this comes with a significant caveat: the contract above
    -- does not hold if GHC can demonstrate that the code preceeding
    -- @touchForeignPtr@ diverges (e.g. by looping infinitely or throwing an
    -- exception). For this reason, you are strongly advised to use instead
    -- 'withForeignPtr' where possible.
    --
    -- Also, note that this function should not be used to express dependencies
    -- between finalizers on 'ForeignPtr's.  For example, if the finalizer for a
    -- 'ForeignPtr' @F1@ calls 'touchForeignPtr' on a second 'ForeignPtr' @F2@,
    -- then the only guarantee is that the finalizer for @F2@ is never started
    -- before the finalizer for @F1@.  They might be started together if for
    -- example both @F1@ and @F2@ are otherwise unreachable, and in that case the
    -- scheduler might end up running the finalizer for @F2@ first.
    --
    -- In general, it is not recommended to use finalizers on separate
    -- objects with ordering constraints between them.  To express the
    -- ordering robustly requires explicit synchronisation using @MVar@s
    -- between the finalizers, but even then the runtime sometimes runs
    -- multiple finalizers sequentially in a single thread (for
    -- performance reasons), so synchronisation between finalizers could
    -- result in artificial deadlock.  Another alternative is to use
    -- explicit reference counting.
    --
    touchForeignPtr :: forall a. ForeignPtr a -> IO ()
    touchForeignPtr (ForeignPtr Addr#
    _ ForeignPtrContents
    r) = ForeignPtrContents -> IO ()
    touch ForeignPtrContents
    r

    touch :: ForeignPtrContents -> IO ()
    touch :: ForeignPtrContents -> IO ()
    touch ForeignPtrContents
    r = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
    -> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s -> case ForeignPtrContents -> State# RealWorld -> State# RealWorld
    touch# ForeignPtrContents
    r State# RealWorld
    s of State# RealWorld
    s' -> (# State# RealWorld
    s', () #)

    unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a
    -- ^This function extracts the pointer component of a foreign
    -- pointer.  This is a potentially dangerous operations, as if the
    -- argument to 'unsafeForeignPtrToPtr' is the last usage
    -- occurrence of the given foreign pointer, then its finalizer(s) will
    -- be run, which potentially invalidates the plain pointer just
    -- obtained.  Hence, 'touchForeignPtr' must be used
    -- wherever it has to be guaranteed that the pointer lives on - i.e.,
    -- has another usage occurrence.
    --
    -- To avoid subtle coding errors, hand written marshalling code
    -- should preferably use 'Foreign.ForeignPtr.withForeignPtr' rather
    -- than combinations of 'unsafeForeignPtrToPtr' and
    -- 'touchForeignPtr'.  However, the latter routines
    -- are occasionally preferred in tool generated marshalling code.
    unsafeForeignPtrToPtr :: forall a. ForeignPtr a -> Ptr a
    unsafeForeignPtrToPtr (ForeignPtr Addr#
    fo ForeignPtrContents
    _) = Addr# -> Ptr a
    forall a. Addr# -> Ptr a
    Ptr Addr#
    fo

    castForeignPtr :: ForeignPtr a -> ForeignPtr b
    -- ^This function casts a 'ForeignPtr'
    -- parameterised by one type into another type.
    castForeignPtr :: forall a b. ForeignPtr a -> ForeignPtr b
    castForeignPtr = ForeignPtr a -> ForeignPtr b
    coerce

    plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
    -- ^Advances the given address by the given offset in bytes.
    --
    -- The new 'ForeignPtr' shares the finalizer of the original,
    -- equivalent from a finalization standpoint to just creating another
    -- reference to the original. That is, the finalizer will not be
    -- called before the new 'ForeignPtr' is unreachable, nor will it be
    -- called an additional time due to this call, and the finalizer will
    -- be called with the same address that it would have had this call
    -- not happened, *not* the new address.
    --
    -- @since 4.10.0.0
    plusForeignPtr :: forall a b. ForeignPtr a -> Int -> ForeignPtr b
    plusForeignPtr (ForeignPtr Addr#
    addr ForeignPtrContents
    c) (I# Int#
    d) = Addr# -> ForeignPtrContents -> ForeignPtr b
    forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
    ForeignPtr (Addr# -> Int# -> Addr#
    plusAddr# Addr#
    addr Int#
    d) ForeignPtrContents
    c

    -- | Causes the finalizers associated with a foreign pointer to be run
    -- immediately. The foreign pointer must not be used again after this
    -- function is called. If the foreign pointer does not support finalizers,
    -- this is a no-op.
    finalizeForeignPtr :: ForeignPtr a -> IO ()
    finalizeForeignPtr :: forall a. ForeignPtr a -> IO ()
    finalizeForeignPtr (ForeignPtr Addr#
    _ ForeignPtrContents
    c) = case ForeignPtrContents
    c of
      PlainForeignPtr IORef Finalizers
    ref -> IORef Finalizers -> IO ()
    foreignPtrFinalizer IORef Finalizers
    ref
      MallocPtr MutableByteArray# RealWorld
    _ IORef Finalizers
    ref -> IORef Finalizers -> IO ()
    foreignPtrFinalizer IORef Finalizers
    ref
      PlainPtr{} -> () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      FinalPtr{} -> () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    {- $commentary

    This is a high-level overview of how 'ForeignPtr' works.
    The implementation of 'ForeignPtr' must accomplish several goals:

    1. Invoke a finalizer once a foreign pointer becomes unreachable.
    2. Support augmentation of finalizers, i.e. 'addForeignPtrFinalizer'.
       As a motivating example, suppose that the payload of a foreign
       pointer is C struct @bar@ that has an optionally NULL pointer field
       @foo@ to an unmanaged heap object. Initially, @foo@ is NULL, and
       later the program uses @malloc@, initializes the object, and assigns
       @foo@ the address returned by @malloc@. When the foreign pointer
       becomes unreachable, it is now necessary to first @free@ the object
       pointed to by @foo@ and then invoke whatever finalizer was associated
       with @bar@. That is, finalizers must be invoked in the opposite order
       they are added.
    3. Allow users to invoke a finalizer promptly if they know that the
       foreign pointer is unreachable, i.e. 'finalizeForeignPtr'.

    How can these goals be accomplished? Goal 1 suggests that weak references
    and finalizers (via 'Weak#' and 'mkWeak#') are necessary. But how should
    they be used and what should their key be?  Certainly not 'ForeignPtr' or
    'ForeignPtrContents'. See the warning in "GHC.Weak" about weak pointers with
    lifted (non-primitive) keys. The two finalizer-supporting data constructors of
    'ForeignPtr' have an @'IORef' 'Finalizers'@ (backed by 'MutVar#') field.
    This gets used in two different ways depending on the kind of finalizer:

    * 'HaskellFinalizers': The first @addForeignPtrConcFinalizer_@ call uses
      'mkWeak#' to attach the finalizer @foreignPtrFinalizer@ to the 'MutVar#'.
      The resulting 'Weak#' is discarded (see @addForeignPtrConcFinalizer_@).
      Subsequent calls to @addForeignPtrConcFinalizer_@ (goal 2) just add
      finalizers onto the list in the 'HaskellFinalizers' data constructor.
    * 'CFinalizers': The first 'addForeignPtrFinalizer' call uses
      'mkWeakNoFinalizer#' to create a 'Weak#'. The 'Weak#' is preserved in the
      'CFinalizers' data constructor. Both the first call and subsequent
      calls (goal 2) use 'addCFinalizerToWeak#' to attach finalizers to the
      'Weak#' itself. Also, see Note [MallocPtr finalizers] for discussion of
      the key and value of this 'Weak#'.

    In either case, the runtime invokes the appropriate finalizers when the
    'ForeignPtr' becomes unreachable.
    -}