For now, turn off the SEH code on Win64
[ghc.git] / rts / RtsMain.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team 1998-2000
4 *
5 * Main function for a standalone Haskell program.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #define COMPILING_RTS_MAIN
10
11 #include "PosixSource.h"
12 #include "Rts.h"
13 #include "RtsAPI.h"
14
15 #include "RtsUtils.h"
16 #include "Prelude.h"
17 #include "Task.h"
18 #if defined(mingw32_HOST_OS)
19 #include "win32/seh_excn.h"
20 #endif
21
22 #ifdef DEBUG
23 # include "Printer.h" /* for printing */
24 #endif
25
26 #ifdef HAVE_WINDOWS_H
27 # include <windows.h>
28 #endif
29
30 /* Annoying global vars for passing parameters to real_main() below
31 * This is to get around problem with Windows SEH, see hs_main(). */
32 static int progargc;
33 static char **progargv;
34 static StgClosure *progmain_closure; /* This will be ZCMain_main_closure */
35 static RtsConfig rtsconfig;
36
37 /* Hack: we assume that we're building a batch-mode system unless
38 * INTERPRETER is set
39 */
40 #ifndef INTERPRETER /* Hack */
41 static void real_main(void) GNUC3_ATTRIBUTE(__noreturn__);
42 static void real_main(void)
43 {
44 int exit_status;
45 SchedulerStatus status;
46
47 hs_init_ghc(&progargc, &progargv, rtsconfig);
48
49 /* kick off the computation by creating the main thread with a pointer
50 to mainIO_closure representing the computation of the overall program;
51 then enter the scheduler with this thread and off we go;
52
53 the same for GranSim (we have only one instance of this code)
54
55 in a parallel setup, where we have many instances of this code
56 running on different PEs, we should do this only for the main PE
57 (IAmMainThread is set in startupHaskell)
58 */
59
60 /* ToDo: want to start with a larger stack size */
61 {
62 Capability *cap = rts_lock();
63 rts_evalLazyIO(&cap,progmain_closure, NULL);
64 status = rts_getSchedStatus(cap);
65 rts_unlock(cap);
66 }
67
68 /* check the status of the entire Haskell computation */
69 switch (status) {
70 case Killed:
71 errorBelch("main thread exited (uncaught exception)");
72 exit_status = EXIT_KILLED;
73 break;
74 case Interrupted:
75 errorBelch("interrupted");
76 exit_status = EXIT_INTERRUPTED;
77 break;
78 case HeapExhausted:
79 exit_status = EXIT_HEAPOVERFLOW;
80 break;
81 case Success:
82 exit_status = EXIT_SUCCESS;
83 break;
84 default:
85 barf("main thread completed with invalid status");
86 }
87 shutdownHaskellAndExit(exit_status);
88 }
89
90 /* The rts entry point from a compiled program using a Haskell main
91 * function. This gets called from a tiny main function generated by
92 * GHC and linked into each compiled Haskell program that uses a
93 * Haskell main function.
94 *
95 * We expect the caller to pass ZCMain_main_closure for
96 * main_closure. The reason we cannot refer to this symbol directly
97 * is because we're inside the rts and we do not know for sure that
98 * we'll be using a Haskell main function.
99 */
100 int hs_main (int argc, char *argv[], // program args
101 StgClosure *main_closure, // closure for Main.main
102 RtsConfig rts_config) // RTS configuration
103 {
104 /* We do this dance with argc and argv as otherwise the SEH exception
105 stuff (the BEGIN/END CATCH below) on Windows gets confused */
106 progargc = argc;
107 progargv = argv;
108 progmain_closure = main_closure;
109 rtsconfig = rts_config;
110
111 #if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH)
112 BEGIN_CATCH
113 #endif
114 real_main();
115 #if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH)
116 END_CATCH
117 #endif
118 }
119 # endif /* BATCH_MODE */