A stable pointer is a reference to a Haskell expression that can be passed to foreign functions via the foreign function interface.
Normally a Haskell object will move around from time to time, because
of garbage collection, hence we can't just pass the address of an
object to a foreign function and expect it to remain valid. Stable
pointers provide a level of indirection so that the foreign code can
get the "real address" of the Haskell object by calling
deRefStablePtr
on the stable pointer object it has.
The Haskell interface provided by the Stable
module is as follows:
data StablePtr a -- abstract, instance of: Eq.
makeStablePtr :: a -> IO (StablePtr a)
deRefStablePtr :: StablePtr a -> IO a
freeStablePtr :: StablePtr a -> IO ()
Care must be taken to free stable pointers that are no longer required
using the freeStablePtr
function, otherwise two bad things can
happen:
Notes:
sp1 :: StablePtr
and sp2 :: StablePtr
and sp1
== sp2
then sp1
and sp2
are either the same stable pointer,
or they were created by calls to makeStablePtr
on the same
object. Another way to say this is "every time you call
makeStablePtr
on an object you get back the same stable pointer".deRefStablePtr
on a stable pointer which has previously been
freed results in undefined behaviour.The C interface (which is brought into scope by #include
<Stable.h>
) is as follows:
typedef StablePtr /* abstract, probably an unsigned long */
extern StgPtr deRefStablePtr(StgStablePtr stable_ptr);
static void freeStablePtr(StgStablePtr sp);
static StgStablePtr splitStablePtr(StgStablePtr sp);
The functions deRefStablePtr
and freeStablePtr
are
equivalent to the Haskell functions of the same name above.
The function splitStablePtr
allows a stable pointer to be
duplicated without making a new one with makeStablePtr
. The
stable pointer won't be removed from the runtime system's internal
table until freeStablePtr
is called on both pointers.