summaryrefslogtreecommitdiff
path: root/rts/RtsMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/RtsMain.c')
-rw-r--r--rts/RtsMain.c121
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 */