/* ----------------------------------------------------------------------------- * * (c) The GHC Team 1998-2000 * * Main function for a standalone Haskell program. * * ---------------------------------------------------------------------------*/ #define COMPILING_RTS_MAIN #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" #include "RtsUtils.h" #include "RtsFlags.h" #include "Prelude.h" #include "Task.h" #include "Excn.h" #if defined(DEBUG) # include "Printer.h" /* for printing */ #endif // Hack: we assume that we're building a batch-mode system unless // INTERPRETER is set #if !defined(INTERPRETER) /* Hack */ // 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 int hs_main ( int argc, char *argv[], // program args StgClosure *main_closure, // closure for Main.main RtsConfig rts_config) // RTS configuration { int exit_status; SchedulerStatus status; // See Note: [Windows Unicode Arguments] in rts/RtsFlags.c #if defined(mingw32_HOST_OS) { argv = getUTF8Args(&argc); } #endif hs_init_ghc(&argc, &argv, rts_config); BEGIN_WINDOWS_VEH_HANDLER // 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; // // 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 { Capability *cap = rts_lock(); rts_evalLazyIO(&cap, main_closure, NULL); status = rts_getSchedStatus(cap); rts_unlock(cap); } // check the status of the entire Haskell computation switch (status) { case Killed: errorBelch("main thread exited (uncaught exception)"); exit_status = EXIT_KILLED; break; case Interrupted: errorBelch("interrupted"); exit_status = EXIT_INTERRUPTED; break; case HeapExhausted: exit_status = EXIT_HEAPOVERFLOW; break; case Success: exit_status = EXIT_SUCCESS; break; default: barf("main thread completed with invalid status"); } END_WINDOWS_VEH_HANDLER shutdownHaskellAndExit(exit_status, 0 /* !fastExit */); // No code beyond this point. Dead code elimination will remove it } # endif /* BATCH_MODE */