c73002f63e8add494becdfd43408179e809acd13
[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 "RtsFlags.h"
17 #include "Prelude.h"
18 #include "Task.h"
19 #include "Excn.h"
20
21 #if defined(DEBUG)
22 # include "Printer.h" /* for printing */
23 #endif
24
25 // Hack: we assume that we're building a batch-mode system unless
26 // INTERPRETER is set
27
28 #if !defined(INTERPRETER) /* Hack */
29
30 // The rts entry point from a compiled program using a Haskell main
31 // function. This gets called from a tiny main function generated by
32 // GHC and linked into each compiled Haskell program that uses a
33 // Haskell main function.
34 //
35 // We expect the caller to pass ZCMain_main_closure for
36 // main_closure. The reason we cannot refer to this symbol directly
37 // is because we're inside the rts and we do not know for sure that
38 // we'll be using a Haskell main function.
39 //
40 // NOTE: This function is marked as _noreturn_ in Main.h
41
42 int hs_main ( int argc, char *argv[], // program args
43 StgClosure *main_closure, // closure for Main.main
44 RtsConfig rts_config) // RTS configuration
45
46 {
47 BEGIN_WINDOWS_VEH_HANDLER
48
49 int exit_status;
50 SchedulerStatus status;
51
52 // See Note: [Windows Unicode Arguments] in rts/RtsFlags.c
53 #if defined(mingw32_HOST_OS)
54 {
55 argv = getUTF8Args(&argc);
56 }
57 #endif
58
59
60
61
62 hs_init_ghc(&argc, &argv, rts_config);
63
64 // kick off the computation by creating the main thread with a pointer
65 // to mainIO_closure representing the computation of the overall program;
66 // then enter the scheduler with this thread and off we go;
67 //
68 // in a parallel setup, where we have many instances of this code
69 // running on different PEs, we should do this only for the main PE
70 // (IAmMainThread is set in startupHaskell)
71
72 // ToDo: want to start with a larger stack size
73 {
74 Capability *cap = rts_lock();
75 rts_evalLazyIO(&cap, main_closure, NULL);
76 status = rts_getSchedStatus(cap);
77 rts_unlock(cap);
78 }
79
80 // check the status of the entire Haskell computation
81 switch (status) {
82 case Killed:
83 errorBelch("main thread exited (uncaught exception)");
84 exit_status = EXIT_KILLED;
85 break;
86 case Interrupted:
87 errorBelch("interrupted");
88 exit_status = EXIT_INTERRUPTED;
89 break;
90 case HeapExhausted:
91 exit_status = EXIT_HEAPOVERFLOW;
92 break;
93 case Success:
94 exit_status = EXIT_SUCCESS;
95 break;
96 default:
97 barf("main thread completed with invalid status");
98 }
99
100 END_WINDOWS_VEH_HANDLER
101
102 shutdownHaskellAndExit(exit_status, 0 /* !fastExit */);
103 // No code beyond this point. Dead code elimination will remove it
104 }
105 # endif /* BATCH_MODE */