[project @ 2001-05-21 14:07:31 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / PrelTopHandler.lhs
1 -- -----------------------------------------------------------------------------
2 -- $Id: PrelTopHandler.lhs,v 1.1 2001/05/21 14:07:31 simonmar Exp $
3 --
4 -- (c) The University of Glasgow, 2001
5 --
6 -- PrelTopHandler
7 --
8 -- 'Top-level' IO actions want to catch exceptions (e.g., forkIO and 
9 -- PrelMain.mainIO) and report them - topHandler is the exception
10 -- handler they should use for this:
11
12 -- make sure we handle errors while reporting the error!
13 -- (e.g. evaluating the string passed to 'error' might generate
14 --  another error, etc.)
15
16 -- These functions can't go in PrelMain, because PrelMain isn't
17 -- included in HSstd.o (because PrelMain depends on Main, which
18 -- doesn't exist yet...).
19
20 \begin{code}
21 module PrelTopHandler (
22    topHandler, reportStackOverflow, reportError 
23   ) where
24
25 import IO
26
27 import PrelCString
28 import PrelPtr
29 import PrelIOBase
30 import PrelException
31
32 topHandler :: Exception -> IO ()
33 topHandler err = catchException (real_handler err) topHandler
34
35 real_handler :: Exception -> IO ()
36 real_handler ex =
37   case ex of
38         AsyncException StackOverflow -> reportStackOverflow True
39         ErrorCall s -> reportError True s
40         other       -> reportError True (showsPrec 0 other "\n")
41
42 reportStackOverflow :: Bool -> IO ()
43 reportStackOverflow bombOut = do
44    (hFlush stdout) `catchException` (\ _ -> return ())
45    callStackOverflowHook
46    if bombOut then
47      stg_exit 2
48     else
49      return ()
50
51 reportError :: Bool -> String -> IO ()
52 reportError bombOut str = do
53    (hFlush stdout) `catchException` (\ _ -> return ())
54    withCStringLen str $ \(cstr,len) -> do
55      writeErrString addrOf_ErrorHdrHook cstr len
56      if bombOut 
57         then stg_exit 1
58         else return ()
59
60 foreign import ccall "addrOf_ErrorHdrHook" unsafe
61         addrOf_ErrorHdrHook :: Ptr ()
62
63 foreign import ccall "writeErrString__" unsafe
64         writeErrString :: Ptr () -> CString -> Int -> IO ()
65
66 -- SUP: Are the hooks allowed to re-enter Haskell land?  If so, remove
67 -- the unsafe below.
68 foreign import ccall "stackOverflow" unsafe
69         callStackOverflowHook :: IO ()
70
71 foreign import ccall "stg_exit" unsafe
72         stg_exit :: Int -> IO ()
73 \end{code}