diff options
Diffstat (limited to 'rts/RtsMain.c')
| -rw-r--r-- | rts/RtsMain.c | 121 |
1 files changed, 49 insertions, 72 deletions
diff --git a/rts/RtsMain.c b/rts/RtsMain.c index 3cf4f54cec..667c9e4ae2 100644 --- a/rts/RtsMain.c +++ b/rts/RtsMain.c @@ -8,6 +8,7 @@ #define COMPILING_RTS_MAIN +#include "Excn.h" #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" @@ -15,105 +16,81 @@ #include "RtsUtils.h" #include "Prelude.h" #include "Task.h" -#if defined(mingw32_HOST_OS) -#include "win32/seh_excn.h" -#endif #ifdef DEBUG # include "Printer.h" /* for printing */ #endif -#ifdef HAVE_WINDOWS_H -# include <windows.h> -#endif +// Hack: we assume that we're building a batch-mode system unless +// INTERPRETER is set + +#ifndef INTERPRETER /* Hack */ -/* Annoying global vars for passing parameters to real_main() below - * This is to get around problem with Windows SEH, see hs_main(). */ -static int progargc; -static char **progargv; -static StgClosure *progmain_closure; /* This will be ZCMain_main_closure */ -static RtsConfig rtsconfig; +// The rts entry point from a compiled program using a Haskell main +// function. This gets called from a tiny main function generated by +// GHC and linked into each compiled Haskell program that uses a +// Haskell main function. +// +// We expect the caller to pass ZCMain_main_closure for +// main_closure. The reason we cannot refer to this symbol directly +// is because we're inside the rts and we do not know for sure that +// we'll be using a Haskell main function. +// +// NOTE: This function is marked as _noreturn_ in Main.h -/* Hack: we assume that we're building a batch-mode system unless - * INTERPRETER is set - */ -#ifndef INTERPRETER /* Hack */ -static void real_main(void) GNUC3_ATTRIBUTE(__noreturn__); -static void real_main(void) +int hs_main ( int argc, char *argv[], // program args + StgClosure *main_closure, // closure for Main.main + RtsConfig rts_config) // RTS configuration + { + BEGIN_WINDOWS_VEH_HANDLER + int exit_status; SchedulerStatus status; - hs_init_ghc(&progargc, &progargv, rtsconfig); - - /* kick off the computation by creating the main thread with a pointer - to mainIO_closure representing the computation of the overall program; - then enter the scheduler with this thread and off we go; - - the same for GranSim (we have only one instance of this code) + hs_init_ghc(&argc, &argv, rts_config); - in a parallel setup, where we have many instances of this code - running on different PEs, we should do this only for the main PE - (IAmMainThread is set in startupHaskell) - */ + // kick off the computation by creating the main thread with a pointer + // to mainIO_closure representing the computation of the overall program; + // then enter the scheduler with this thread and off we go; + // + // the same for GranSim (we have only one instance of this code) + // + // in a parallel setup, where we have many instances of this code + // running on different PEs, we should do this only for the main PE + // (IAmMainThread is set in startupHaskell) - /* ToDo: want to start with a larger stack size */ + // ToDo: want to start with a larger stack size { Capability *cap = rts_lock(); - rts_evalLazyIO(&cap,progmain_closure, NULL); + rts_evalLazyIO(&cap, main_closure, NULL); status = rts_getSchedStatus(cap); rts_unlock(cap); } - /* check the status of the entire Haskell computation */ + // check the status of the entire Haskell computation switch (status) { case Killed: - errorBelch("main thread exited (uncaught exception)"); - exit_status = EXIT_KILLED; - break; + errorBelch("main thread exited (uncaught exception)"); + exit_status = EXIT_KILLED; + break; case Interrupted: - errorBelch("interrupted"); - exit_status = EXIT_INTERRUPTED; - break; + errorBelch("interrupted"); + exit_status = EXIT_INTERRUPTED; + break; case HeapExhausted: - exit_status = EXIT_HEAPOVERFLOW; - break; + exit_status = EXIT_HEAPOVERFLOW; + break; case Success: - exit_status = EXIT_SUCCESS; - break; + exit_status = EXIT_SUCCESS; + break; default: - barf("main thread completed with invalid status"); + barf("main thread completed with invalid status"); } - shutdownHaskellAndExit(exit_status, 0 /* !fastExit */); -} -/* The rts entry point from a compiled program using a Haskell main - * function. This gets called from a tiny main function generated by - * GHC and linked into each compiled Haskell program that uses a - * Haskell main function. - * - * We expect the caller to pass ZCMain_main_closure for - * main_closure. The reason we cannot refer to this symbol directly - * is because we're inside the rts and we do not know for sure that - * we'll be using a Haskell main function. - */ -int hs_main (int argc, char *argv[], // program args - StgClosure *main_closure, // closure for Main.main - RtsConfig rts_config) // RTS configuration -{ - /* We do this dance with argc and argv as otherwise the SEH exception - stuff (the BEGIN/END CATCH below) on Windows gets confused */ - progargc = argc; - progargv = argv; - progmain_closure = main_closure; - rtsconfig = rts_config; + END_WINDOWS_VEH_HANDLER -#if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH) - BEGIN_CATCH -#endif - real_main(); -#if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH) - END_CATCH -#endif + shutdownHaskellAndExit(exit_status, 0 /* !fastExit */); + // No code beyond this point. Dead code elimination will remove it } # endif /* BATCH_MODE */ |
