This module provides two kinds of stable references to Haskell objects, stable names and stable pointers.
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.
A haskell object can be given a stable name by calling
makeStableName on it. Stable names solve the following problem:
suppose you want to build a hash table with Haskell objects as keys,
but you want to use pointer equality for comparison; maybe because the
keys are large and hashing would be slow, or perhaps because the keys
are infinite in size. We can't build a hash table using the address
of the object as the key, because objects get moved around by the
garbage collector, meaning a re-hash would be necessary after every
garbage collection.
Enter stable names. A stable name is an abstract entity that supports equality and hashing, with the following interface:
data StableName a -- abstract, instance Eq.
makeStableName :: a -> IO (StableName a)
hashStableName :: StableName a -> Int
All these operations run in constant time.
Stable names have the following properties:
sn1 :: StablePtr and sn2 :: StablePtr and sn1
== sn2 then sn1 and sn2 are either the same stable name,
or they were created by calls to makeStableName on the same
object.freeStableName operation. Stable names are
reclaimed by the runtime system when they are no longer needed.deRefStableName operation. You can't get back
from a stable name to the original Haskell object. The reason for
this is that the existence of a stable name for an object doesn't
guarantee the existence of the object itself; it can still be garbage
collected. hashStableName operation, which converts a
stable name to an Int. The Int returned is not necessarily
unique (that is, it doesn't satisfy property (1) above), but it can be
used for building hash tables of stable names.Properties (1) and (2) are similar to stable pointers, but the key
differences are that you can't get back to the original object from a
stable name, and you can convert one to an Int for hashing.