ForeignPtr representation

Simon Marlow marlowsd at
Thu Sep 6 07:15:15 UTC 2018

Wouldn't this mean that unpacking a ForeignPtr is one word longer than it
is now? That would have a big impact on ByteString.

What do you think is redundant in the current representation?


On Wed, 5 Sep 2018 at 00:23, David Feuer <david.feuer at> wrote:

> I'm trying, and failing, to understand why ForeignPtr is defined the way
> it is. It all seems rather complicated and redundant. I was thinking we
> might want to switch to something simpler and more explicit, like this:
> data ForeignPtr a = ForeignPtr {
>   fptr :: !(Ptr a) -- What we point to
>   froot :: MutableByteArray# RealWorld
>   fwk :: MutVar# RealWorld Any -- The finalizers
>   }
> froot represents the object the ForeignPtr points into. When created by
> one of the malloc variants, this will actually be the allocated byte array.
> Otherwise, it will be a 0-length array.
> fwk should be seen as having type
>   fwk :: MutVar# RealWorld (Weak# (MutableByteArray# RealWorld))
> but we can't express that directly right now. fwk is keyed on froot, and
> in the malloc case also points to it, to prevent it from being freed
> prematurely.
> It seems that this representation requires a couple extra primitive
> features from Weak#. I think that's okay: Weak# already has some primitive
> features designed to support ForeignPtr.
> 1. An operation to add a Haskell finalizer to a Weak#, similar to the one
> that adds a C finalizer.
> 2. A way to deal with mixed finalizers: either make the finalizer-adding
> primops report distinguishable failure on mixing or arrange to run the C
> finalizers after any Haskell finalizers (since C finalizers are much more
> likely to actually invalidate the pointer).
> 3. A documented guarantee about the order in which the finalizers attached
> to a particular Weak# run, compatible with the ForeignPtr documentation.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list