diff options
Diffstat (limited to 'ghc/docs/users_guide/glasgow_exts.lit')
-rw-r--r-- | ghc/docs/users_guide/glasgow_exts.lit | 318 |
1 files changed, 184 insertions, 134 deletions
diff --git a/ghc/docs/users_guide/glasgow_exts.lit b/ghc/docs/users_guide/glasgow_exts.lit index f09235b4c5..b10b282dac 100644 --- a/ghc/docs/users_guide/glasgow_exts.lit +++ b/ghc/docs/users_guide/glasgow_exts.lit @@ -28,18 +28,12 @@ to the raw machine types and operations; included in this are ``primitive arrays'' (direct access to Big Wads of Bytes). Please see \Sectionref{glasgow-unboxed} and following. -%\item[Synchronising variables---\tr{_IVar}s, \tr{_MVar}s:] -%These are used when reads and writes need to be coordinated, -%e.g., if the readers and writers are different concurrent threads. -%Please see \Sectionref{ivars-mvars}. - \item[Calling out to C:] Just what it sounds like. We provide {\em lots} of rope that you can dangle around your neck. Please see \Sectionref{glasgow-ccalls}. -\item[``Monadic I/O:''] This stuff will be coming to you For Real -with Haskell~1.3, whenever that is. -Please see \Sectionref{io-1-3} (the ``1.3 I/O'' section). +\item[Low-level monadic I/O:] Monadic I/O is now standard with Haskell~1.3; +you can still get access to the system at a lower level (the ``PrimIO'' level). \item[``HBC-ish'' extensions:] Extensions implemented because people said, ``HBC does Y. Could you teach GHC to do the same?'' Please see @@ -138,13 +132,13 @@ That is, GHC provides a safe way to pass Haskell pointers to C. Please see \Sectionref{glasgow-stablePtrs} for more details. -\item[``Malloc'' pointers:] -A ``malloc'' pointer is a safe way to pass a C~pointer to Haskell and +\item[``Foreign objects'':] +A ``foreign object'' is a safe way to pass a C~pointer to Haskell and have Haskell do the Right Thing when it no longer references the object. So, for example, C could pass a large bitmap over to Haskell and say ``please free this memory when you're done with it.'' -Please see \Sectionref{glasgow-mallocPtrs} for more details. +Please see \Sectionref{glasgow-foreignObjs} for more details. \end{description} See sections~1.4 and~1.6 of the ``state interface document'' for the @@ -153,6 +147,35 @@ them. %************************************************************************ +%* * +\subsection[own-mainPrimIO]{Using your own @mainPrimIO@} +\index{mainPrimIO, rolling your own} +%* * +%************************************************************************ + +Normally, the GHC runtime system begins things by called an internal +function @mainPrimIO :: PrimIO ()@ which, in turn, fires up +your @Main.main@. + +To subvert the above process, you need only provide a +@mainPrimIO :: PrimIO ()@ of your own (in a module named \tr{GHCmain}). + +Here's a little example, stolen from Alastair Reid: +\begin{verbatim} +module GHCmain ( mainPrimIO ) where + +import PreludeGlaST + +mainPrimIO :: PrimIO () +mainPrimIO = do + sleep 5 + _ccall_ printf "%d\n" (14::Int) + +sleep :: Int -> PrimIO () +sleep t = _ccall_ sleep t +\end{verbatim} + +%************************************************************************ %* * \subsection[glasgow-ccalls]{Calling~C directly from Haskell} \index{C calls (Glasgow extension)} @@ -166,25 +189,14 @@ them. %import PreludePrimIO %\end{verbatim} -SINCE VERSION 0.22: ``Literal-literals'', e.g., \tr{``NULL''}, can now -be any `boxed-primitive' type---they are not automatically taken to be -\tr{_Addr}s. This is cool, except you may sometimes have to put in -a type signature to force the desired type. - -SINCE VERSION 0.19: \tr{ccall} and \tr{casm} have been renamed to -\tr{_ccall_} and \tr{_casm_} and \tr{veryDangerousCcall} and -\tr{veryDangerousCasm} have been removed. It is no longer necessary -(nor legal!) to unbox/rebox the arguments and results to @_ccall_@. -GHC does the unboxing/reboxing for you. - GOOD ADVICE: Because this stuff is not Entirely Stable as far as names and things go, you would be well-advised to keep your C-callery corraled in a few modules, rather than sprinkled all over your code. It will then be quite easy to update later on. -WARNING AS OF 0.26: Yes, the \tr{_ccall_} stuff probably {\em will -change}, to something better, of course! We are only at the -musing-about-it stage, however. +WARNING AS OF 2.01: Yes, the \tr{_ccall_} stuff probably {\em will +change}, to something better, of course! We are still at the +musing-about-it stage, however... %************************************************************************ %* * @@ -196,16 +208,16 @@ The simplest way to use a simple C function \begin{verbatim} double fooC( FILE *in, char c, int i, double d, unsigned int u ) \end{verbatim} -is to provide a Haskell wrapper +is to provide a Haskell wrapper: \begin{verbatim} -fooH :: Char -> Int -> Double -> _Word -> PrimIO Double +fooH :: Char -> Int -> Double -> Word -> PrimIO Double fooH c i d w = _ccall_ fooC ``stdin'' c i d w \end{verbatim} The function @fooH@ will unbox all of its arguments, call the C function \tr{fooC} and box the corresponding arguments. So, if you want to do C-calling, you have to confront the underlying -Glasgow I/O system. It's just your typical monad whatnot. +I/O system (at the ``PrimIO'' level). %The code in \tr{ghc/lib/glaExts/*.lhs} is not too obtuse. %That code, plus \tr{lib/prelude/Builtin.hs}, give examples @@ -218,12 +230,12 @@ may be just the ticket (NB: {\em no chance} of such code going through a native-code generator): \begin{verbatim} oldGetEnv name - = _casm_ ``%r = getenv((char *) %0);'' name `thenPrimIO` \ litstring@(A# str#) -> - returnPrimIO ( + = _casm_ ``%r = getenv((char *) %0);'' name >>= \ litstring@(A# str#) -> + return ( if (litstring == ``NULL'') then - Failure (SearchError ("GetEnv:"++name)) + Left ("Fail:oldGetEnv:"++name) else - Str (unpackCString# str#) + Right (unpackCString# str#) ) \end{verbatim} @@ -246,18 +258,18 @@ directive to provide \tr{.h} files containing function headers. For example, \begin{verbatim} -typedef unsigned long *StgMallocPtr; +typedef unsigned long *StgForeignObj; typedef long StgInt; -void initialiseEFS PROTO( (StgInt size) ); -StgInt terminateEFS (); -StgMallocPtr emptyEFS(); -StgMallocPtr updateEFS PROTO( (StgMallocPtr a, StgInt i, StgInt x) ); -StgInt lookupEFS PROTO( (StgMallocPtr a, StgInt i) ); +void initialiseEFS (StgInt size); +StgInt terminateEFS (void); +StgForeignObj emptyEFS(void); +StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x); +StgInt lookupEFS (StgForeignObj a, StgInt i); \end{verbatim} You can find appropriate definitions for \tr{StgInt}, -\tr{StgMallocPtr}, etc using \tr{gcc} on your architecture by +\tr{StgForeignObj}, etc using \tr{gcc} on your architecture by consulting \tr{ghc/includes/StgTypes.lh}. The following table summarises the relationship between Haskell types and C types. @@ -277,7 +289,7 @@ C type name & Haskell Type \\ \hline \tr{StgByteArray} & \tr{MutableByteArray#}\\ \tr{StgStablePtr} & \tr{StablePtr#}\\ -\tr{StgMallocPtr} & \tr{MallocPtr#} +\tr{StgForeignObj} & \tr{MallocPtr#} \end{tabular} Note that this approach is only {\em essential\/} for returning @@ -301,32 +313,31 @@ unevaluated arguments and require the C programmer to force their evaluation before using them. \item Boxed values are stored on the Haskell heap and may be moved -within the heap if a garbage collection occurs --- that is, pointers +within the heap if a garbage collection occurs---that is, pointers to boxed objects are not {\em stable\/}. \end{itemize} It is possible to subvert the unboxing process by creating a ``stable -pointer'' to a value and passing the stable pointer instead. (To use -stable pointers, you must \tr{import PreludeGlaMisc}.) For example, to +pointer'' to a value and passing the stable pointer instead. For example, to pass/return an integer lazily to C functions \tr{storeC} and \tr{fetchC}, one might write: \begin{verbatim} storeH :: Int -> PrimIO () -storeH x = makeStablePtr x `thenPrimIO` \ stable_x -> +storeH x = makeStablePtr x >>= \ stable_x -> _ccall_ storeC stable_x fetchH :: PrimIO Int -fetchH x = _ccall_ fetchC `thenPrimIO` \ stable_x -> - deRefStablePtr stable_x `thenPrimIO` \ x -> - freeStablePtr stable_x `seqPrimIO` - returnPrimIO x +fetchH x = _ccall_ fetchC >>= \ stable_x -> + deRefStablePtr stable_x >>= \ x -> + freeStablePtr stable_x >> + return x \end{verbatim} The garbage collector will refrain from throwing a stable pointer away until you explicitly call one of the following from C or Haskell. \begin{verbatim} void freeStablePointer( StgStablePtr stablePtrToToss ) -freeStablePtr :: _StablePtr a -> PrimIO () +freeStablePtr :: StablePtr a -> PrimIO () \end{verbatim} As with the use of \tr{free} in C programs, GREAT CARE SHOULD BE @@ -340,9 +351,9 @@ message from the runtime system); too late and you get space leaks. %call one of the following C functions (according to type of argument). % %\begin{verbatim} -%void performIO ( StgStablePtr stableIndex /* _StablePtr s (PrimIO ()) */ ); -%StgInt enterInt ( StgStablePtr stableIndex /* _StablePtr s Int */ ); -%StgFloat enterFloat ( StgStablePtr stableIndex /* _StablePtr s Float */ ); +%void performIO ( StgStablePtr stableIndex /* StablePtr s (PrimIO ()) */ ); +%StgInt enterInt ( StgStablePtr stableIndex /* StablePtr s Int */ ); +%StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ ); %\end{verbatim} % %ToDo ADR: test these functions! @@ -352,26 +363,25 @@ message from the runtime system); too late and you get space leaks. %************************************************************************ %* * -\subsubsection[glasgow-mallocPtrs]{Pointing outside the Haskell heap} -\index{malloc pointers (Glasgow extension)} +\subsubsection[glasgow-foreignObjs]{Pointing outside the Haskell heap} +\index{foreign objects (Glasgow extension)} %* * %************************************************************************ There are two types that \tr{ghc} programs can use to reference -(heap-allocated) objects outside the Haskell world: \tr{_Addr} and -\tr{_MallocPtr}. (You must import \tr{PreludeGlaMisc} to use -\tr{_MallocPtr}.) +(heap-allocated) objects outside the Haskell world: \tr{Addr} and +\tr{ForeignObj}. -If you use \tr{_Addr}, it is up to you to the programmer to arrange +If you use \tr{Addr}, it is up to you to the programmer to arrange allocation and deallocation of the objects. -If you use \tr{_MallocPtr}, \tr{ghc}'s garbage collector will +If you use \tr{ForeignObj}, \tr{ghc}'s garbage collector will call the user-supplied C function \begin{verbatim} -void FreeMallocPtr( StgMallocPtr garbageMallocPtr ) +void freeForeignObj( StgForeignObj garbageMallocPtr ) \end{verbatim} when the Haskell world can no longer access the object. Since -\tr{_MallocPtr}s only get released when a garbage collection occurs, +\tr{ForeignObj}s only get released when a garbage collection occurs, we provide ways of triggering a garbage collection from within C and from within Haskell. \begin{verbatim} @@ -403,14 +413,13 @@ atan2d :: Double -> Double -> Double atan2d y x = unsafePerformPrimIO (_ccall_ atan2d y x) sincosd :: Double -> (Double, Double) -sincosd x = unsafePerformPrimIO ( - newDoubleArray (0, 1) `thenPrimIO` \ da -> +sincosd x = unsafePerformPrimIO $ + newDoubleArray (0, 1) >>= \ da -> _casm_ ``sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );'' x da - `seqPrimIO` - readDoubleArray da 0 `thenPrimIO` \ s -> - readDoubleArray da 1 `thenPrimIO` \ c -> - returnPrimIO (s, c) - ) + >> + readDoubleArray da 0 >>= \ s -> + readDoubleArray da 1 >>= \ c -> + return (s, c) \end{verbatim} \item Calling a set of functions which have side-effects but which can @@ -426,34 +435,34 @@ lookup :: EFS a -> Int -> a empty = unsafePerformPrimIO (_ccall_ emptyEFS) -update a i x = unsafePerformPrimIO ( - makeStablePtr x `thenPrimIO` \ stable_x -> +update a i x = unsafePerformPrimIO $ + makeStablePtr x >>= \ stable_x -> _ccall_ updateEFS a i stable_x - ) -lookup a i = unsafePerformPrimIO ( - _ccall_ lookupEFS a i `thenPrimIO` \ stable_x -> +lookup a i = unsafePerformPrimIO $ + _ccall_ lookupEFS a i >>= \ stable_x -> deRefStablePtr stable_x - ) \end{verbatim} -You will almost always want to use \tr{_MallocPtr}s with this. +You will almost always want to use \tr{ForeignObj}s with this. \item Calling a side-effecting function even though the results will be unpredictable. For example the \tr{trace} function is defined by: \begin{verbatim} trace :: String -> a -> a -trace string expr = unsafePerformPrimIO ( - appendChan# ``stderr'' "Trace On:\n" `seqPrimIO` - appendChan# ``stderr'' string `seqPrimIO` - appendChan# ``stderr'' "\nTrace Off.\n" `seqPrimIO` - returnPrimIO expr ) +trace string expr + = unsafePerformPrimIO ( + ((_ccall_ PreTraceHook sTDERR{-msg-}):: PrimIO ()) >> + fputs sTDERR string >> + ((_ccall_ PostTraceHook sTDERR{-msg-}):: PrimIO ()) >> + returnPrimIO expr ) + where + sTDERR = (``stderr'' :: Addr) \end{verbatim} (This kind of use is not highly recommended --- it is only really useful in debugging code.) - \end{itemize} %************************************************************************ @@ -501,7 +510,7 @@ the intermediate C (\tr{.hc} file). The compiler uses two non-standard type-classes when type-checking the arguments and results of \tr{_ccall_}: the arguments (respectively result) of \tr{_ccall_} must be instances of the class -\tr{_CCallable} (respectively \tr{_CReturnable}. (Neither class +\tr{CCallable} (respectively \tr{CReturnable}). (Neither class defines any methods --- their only function is to keep the type-checker happy.) @@ -527,22 +536,22 @@ Type &CCallable&CReturnable & Which is probably... \\ \hline %------ ---------- ------------ ------------- \tr{Char} & Yes & Yes & \tr{unsigned char} \\ \tr{Int} & Yes & Yes & \tr{long int} \\ -\tr{_Word} & Yes & Yes & \tr{unsigned long int} \\ -\tr{_Addr} & Yes & Yes & \tr{char *} \\ +\tr{Word} & Yes & Yes & \tr{unsigned long int} \\ +\tr{Addr} & Yes & Yes & \tr{char *} \\ \tr{Float} & Yes & Yes & \tr{float} \\ \tr{Double} & Yes & Yes & \tr{double} \\ \tr{()} & No & Yes & \tr{void} \\ \tr{[Char]} & Yes & No & \tr{char *} (null-terminated) \\ \tr{Array} & Yes & No & \tr{unsigned long *}\\ -\tr{_ByteArray} & Yes & No & \tr{unsigned long *}\\ -\tr{_MutableArray} & Yes & No & \tr{unsigned long *}\\ -\tr{_MutableByteArray} & Yes & No & \tr{unsigned long *}\\ - -\tr{_State} & Yes & Yes & nothing!\\ - -\tr{_StablePtr} & Yes & Yes & \tr{unsigned long *}\\ -\tr{_MallocPtr} & Yes & Yes & see later\\ +\tr{ByteArray} & Yes & No & \tr{unsigned long *}\\ +\tr{MutableArray} & Yes & No & \tr{unsigned long *}\\ +\tr{MutableByteArray} & Yes & No & \tr{unsigned long *}\\ + +\tr{State} & Yes & Yes & nothing!\\ + +\tr{StablePtr} & Yes & Yes & \tr{unsigned long *}\\ +\tr{ForeignObjs} & Yes & Yes & see later\\ \end{tabular} The brave and careful programmer can add their own instances of these @@ -550,7 +559,7 @@ classes for the following types: \begin{itemize} \item A {\em boxed-primitive} type may be made an instance of both -\tr{_CCallable} and \tr{_CReturnable}. +\tr{CCallable} and \tr{CReturnable}. A boxed primitive type is any data type with a single unary constructor with a single primitive argument. For @@ -560,27 +569,27 @@ example, the following are all boxed primitive types: Int Double data XDisplay = XDisplay Addr# -data EFS a = EFS# MallocPtr# +data EFS a = EFS# ForeignObj# \end{verbatim} \begin{verbatim} -instance _CCallable (EFS a) -instance _CReturnable (EFS a) +instance CCallable (EFS a) +instance CReturnable (EFS a) \end{verbatim} \item Any datatype with a single nullary constructor may be made an -instance of \tr{_CReturnable}. For example: +instance of \tr{CReturnable}. For example: \begin{verbatim} data MyVoid = MyVoid -instance _CReturnable MyVoid +instance CReturnable MyVoid \end{verbatim} -\item As at version 0.26, \tr{String} (i.e., \tr{[Char]}) is still -not a \tr{_CReturnable} type. +\item As at version 2.01, \tr{String} (i.e., \tr{[Char]}) is still +not a \tr{CReturnable} type. -Also, the now-builtin type \tr{_PackedString} is neither -\tr{_CCallable} nor \tr{_CReturnable}. (But there are functions in +Also, the now-builtin type \tr{PackedString} is neither +\tr{CCallable} nor \tr{CReturnable}. (But there are functions in the PackedString interface to let you get at the necessary bits...) \end{itemize} @@ -606,6 +615,47 @@ hairy with a capital H! %************************************************************************ %************************************************************************ +%* * +\subsubsection[glasgow-prim-interface]{Access to the \tr{PrimIO} monad} +\index{PrimIO monad (Glasgow extension)} +\index{I/O, primitive (Glasgow extension)} +%* * +%************************************************************************ + +The \tr{IO} monad (new in Haskell~1.3) catches errors and passes them +along. It is built on top of the \tr{ST} state-transformer monad. + +A related (and inter-operable-with) monad is the \tr{PrimIO} monad +(NB: the level at which @_ccall_@s work...), where you handle errors +yourself. + +Should you wish to use the \tr{PrimIO} monad directly, you can import +\tr{PreludeGlaST}. It makes available the usual monadic stuff (@>>=@, +@>>@, @return@, etc.), as well as these functions: +\begin{verbatim} +-- for backward compatibility: +returnPrimIO :: a -> PrimIO a +thenPrimIO :: PrimIO a -> (a -> PrimIO b) -> PrimIO b +seqPrimIO :: PrimIO a -> PrimIO b -> PrimIO b + +-- still useful: +fixPrimIO :: (a -> PrimIO a) -> PrimIO a +forkPrimIO :: PrimIO a -> PrimIO a +listPrimIO :: [PrimIO a] -> PrimIO [a] +mapAndUnzipPrimIO :: (a -> PrimIO (b,c)) -> [a] -> PrimIO ([b],[c]) +mapPrimIO :: (a -> PrimIO b) -> [a] -> PrimIO [b] + +unsafePerformPrimIO :: PrimIO a -> a +unsafeInterleavePrimIO :: PrimIO a -> PrimIO a + -- and they are not called "unsafe" for nothing! + +-- to convert back and forth between IO and PrimIO +ioToPrimIO :: IO a -> PrimIO a +primIOToIO :: PrimIO a -> IO a +\end{verbatim} + + +%************************************************************************ %* * \subsection[glasgow-hbc-exts]{``HBC-ish'' extensions implemented by GHC} \index{HBC-like Glasgow extensions} @@ -638,39 +688,39 @@ As Lennart says, ``This is a dubious feature and should not be used carelessly.'' See also: \tr{SPECIALIZE instance} pragmas, in \Sectionref{faster}. - +% %------------------------------------------------------------------- -\item[Signal-handling I/O request:] -\index{signal handling (extension)} -\index{SigAction I/O request} -The Haskell-1.2 I/O request \tr{SigAction n act} installs a signal handler for signal -\tr{n :: Int}. The number is the usual UNIX signal number. The action -is of this type: -\begin{verbatim} -data SigAct - = SAIgnore - | SADefault - | SACatch Dialogue -\end{verbatim} - -The corresponding continuation-style I/O function is the unsurprising: -\begin{verbatim} -sigAction :: Int -> SigAct -> FailCont -> SuccCont -> Dialogue -\end{verbatim} - -When a signal handler is installed with \tr{SACatch}, receipt of the -signal causes the current top-level computation to be abandoned, and -the specified dialogue to be executed instead. The abandoned -computation may leave some partially evaluated expressions in a -non-resumable state. If you believe that your top-level computation -and your signal handling dialogue may share subexpressions, you should -execute your program with the \tr{-N} RTS option, to prevent -black-holing. - -The \tr{-N} option is not available with concurrent/parallel programs, -so great care should be taken to avoid shared subexpressions between -the top-level computation and any signal handlers when using threads. - +% \item[Signal-handling I/O request:] +% \index{signal handling (extension)} +% \index{SigAction I/O request} +% The Haskell-1.2 I/O request \tr{SigAction n act} installs a signal handler for signal +% \tr{n :: Int}. The number is the usual UNIX signal number. The action +% is of this type: +% \begin{verbatim} +% data SigAct +% = SAIgnore +% | SADefault +% | SACatch Dialogue +% \end{verbatim} +% +% The corresponding continuation-style I/O function is the unsurprising: +% \begin{verbatim} +% sigAction :: Int -> SigAct -> FailCont -> SuccCont -> Dialogue +% \end{verbatim} +% +% When a signal handler is installed with \tr{SACatch}, receipt of the +% signal causes the current top-level computation to be abandoned, and +% the specified dialogue to be executed instead. The abandoned +% computation may leave some partially evaluated expressions in a +% non-resumable state. If you believe that your top-level computation +% and your signal handling dialogue may share subexpressions, you should +% execute your program with the \tr{-N} RTS option, to prevent +% black-holing. +% +% The \tr{-N} option is not available with concurrent/parallel programs, +% so great care should be taken to avoid shared subexpressions between +% the top-level computation and any signal handlers when using threads. +% %------------------------------------------------------------------- %\item[Simple time-out mechanism, in ``monadic I/O'':] %\index{time-outs (extension)} |