This module is part of the Foreign Function Interface (FFI) and will usually be imported via the module Foreign (see Section 4.9). A stable pointer is a reference to a Haskell expression that is guaranteed not to be affected by garbage collection, i.e., it will neither be deallocated nor will the value of the stable pointer itself change during garbage collection (ordinary references may be relocated during garbage collection). Consequently, stable pointers can be passed to foreign code, which can handle it as an opaque reference to a Haskell value.
module StablePtr where data StablePtr a -- abstract stable reference to a Haskell value instance Eq StablePtr makeStablePtr :: a -> IO (StablePtr a) deRefStablePtr :: StablePtr a -> IO a freeStablePtr :: StablePtr a -> IO () stablePtrToAddr :: StablePtr a -> Addr addrToStablePtr :: Addr -> StablePtr a |
The behaviour of the functions is as follows:
Creates a stable pointer referring to the given Hasell value.
Obtains the Haskell value referenced by a stable pointer, i.e., the same value that was passed to the corresponding call to makeStablePtr.
Dissolve the association between the stable pointer and the Haskell value. Afterwards, if the stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined. However, the stable pointer may still be passed to stablePtrToAddr, but the Addr value returned by stablePtrToAddr, in this case, is undefined (in particular, it may be Addr.nullAddr). Nevertheless, the call is guaranteed not to diverge.
Coerces a stable pointer to an address. No guarantees are made about the resulting value, except that the original stable pointer can be recovered by addrToStablePtr. In particular, the address may not refer to a valid memory address and any attempt to pass it to the member functions of the class Storable (Section 4.25) will most likely lead to disaster.
The inverse of stablePtrToAddr, i.e., we have the identity
sp == addrToStablePtr (stablePtrToAddr sp) |
for any stable pointer sp on which freeStablePtr has not been executed yet.
Care must be taken to free stable pointers that are no longer required using the function freeStablePtr; otherwise, two bad things can happen:
The object referenced by the stable pointer will be retained in the heap.
The runtime system's internal stable pointer table will grow, which imposes an overhead on garbage collection.
The following definition is available to C programs inter-operating with Haskell code when including the header HsFFI.h.
typedef void* HsStablePtr; /* C representation of a StablePtr */ |
Note that no assumptions may be made about the values representing stable pointer. In fact, they need not even be valid memory addresses. The only guarantee provided is that if they are passed back to Haskell land, the function deRefStablePtr will be able to reconstruct the Haskell value refereed to by the stable pointer.
The following functions are deprecated in the new FFI and the assertions regarding the equality of stable pointers are not guaranteed. Do not use the following functions if you are interested in portability. Most of these functions are here for legacy reasons and may just vanish one day. You have been warned.
Notes:
If 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".
The reverse is not necessarily true: if two stable pointers are not equal, it doesn't mean that they don't refer to the same Haskell object (although they probably don't).
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.