Commit d3a2dc1e authored by simonmar's avatar simonmar

[project @ 2002-06-27 15:38:58 by simonmar]

Finally fix foreign export and foreign import "wrapper" so that
exceptions raised during the call are handled properly rather than
causing the RTS to bomb out.

In particular, calling System.exitWith in a foreign export will cause
the program to terminate cleanly with the desired exit code.  All
other exceptions are printed on stderr (and the program is
terminated).

Details:

GHC.TopHandler.runMain is now called runIO, and has type IO a -> IO a
(previously it had type IO a -> IO (), but that's not general enough
for a foreign export).  The stubs for foreign export and forein import
"wrapper" now automatically wrap the computation in runIO or its dual,
runNonIO.  It turned out to be simpler to do it this way than to do
the wrapping in Haskell land (plain foreign exports don't have
wrappers in Haskell).
parent 5124d8ce
......@@ -19,3 +19,7 @@ test "ffi003" { skip when $platform == "alpha-dec-osf3" -- no NCG on Alpha yet
test "ffi004" { vtr("-fglasgow-exts", "", "") }
test "ffi005" { vtr("-fglasgow-exts", "", "3") }
test "ffi006" { vtr("-fglasgow-exts", "", "") }
test "ffi007" { vtr("-fglasgow-exts", "", "") }
test "ffi008" { vtr("-fglasgow-exts", "", "1") }
-- !!! Test that we can call a foreign import "wrapper" using foreign
-- import "dynamic", in both IO and non-IO flavours.
import Foreign
import Foreign.C
type IOF = Int -> IO Int
type F = Int -> Int
foreign import ccall "wrapper" wrap_f :: F -> IO (FunPtr F)
foreign import ccall "wrapper" wrap_f_io :: IOF -> IO (FunPtr IOF)
foreign import ccall "dynamic" f :: FunPtr F -> F
foreign import ccall "dynamic" f_io :: FunPtr IOF -> IOF
double :: Int -> Int
double x = x * 2
double_io :: Int -> IO Int
double_io x = return (x * 2)
main = do
double1 <- wrap_f double
print (f double1 42)
double2 <- wrap_f_io double_io
x <- f_io double2 42
print x
-- !!! Test System.Exit.exitWith called from a foreign import "wrapper"
import Foreign
import Foreign.C
import System.Exit
type IOF = IO ()
foreign import ccall "wrapper" wrap_f_io :: IOF -> IO (FunPtr IOF)
foreign import ccall "dynamic" call_io :: FunPtr IOF -> IOF
exit = do putStrLn "exiting..."; exitWith ExitSuccess
main = do f <- wrap_f_io exit; call_io f
-- !!! Test exceptions in a foreign import "wrapper"
import Foreign
import Foreign.C
import System.Exit
type IOF = IO ()
foreign import ccall "wrapper" wrap_f_io :: IOF -> IO (FunPtr IOF)
foreign import ccall "dynamic" call_io :: FunPtr IOF -> IOF
mk_error = error "this is an error"
main = do f <- wrap_f_io mk_error; call_io f
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment