summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-12-30 11:02:48 +0200
committerZahary Karadjov <zahary@gmail.com>2013-12-30 11:02:48 +0200
commit046d829e5d9c07cd829de9fa4ec2c9a07bbcf859 (patch)
tree65b2a5676ef357ae1a6e0e289e7b7e8479e85e9a /compiler
parente3f53409f64a74e2f672a1624de17efc84be55ed (diff)
downloadNim-046d829e5d9c07cd829de9fa4ec2c9a07bbcf859.tar.gz
Introduce a PreMain proc in the C codegen
The rationale here is that it has become too hard to step into a program
when #line directives are enabled. You have to skip over many lines of init
code that doesn't have corresponding lines in the nimrod program.
Now, you can just step-out of PreMain and go straight to the useful code
in NimMain.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cgen.nim98
-rw-r--r--compiler/cgendata.nim3
2 files changed, 62 insertions, 39 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 3aef60fa6..b08647512 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -943,44 +943,60 @@ proc genFilenames(m: BModule): PRope =
   for i in 0.. <fileInfos.len:
     result.appf("dbgRegisterFilename($1);$n", fileInfos[i].projPath.makeCString)
 
-proc genMainProc(m: BModule) = 
+proc genMainProc(m: BModule) =
   const 
-    CommonMainBody =
-        "\tsystemDatInit();$n" &
-        "\tsystemInit();$n" &
-        "$1" &
-        "$2" &
-        "$3" &
-        "$4"
-    PosixNimMain = 
-        "int cmdCount;$n" & 
-        "char** cmdLine;$n" & 
-        "char** gEnv;$n" &
-        "N_CDECL(void, NimMain)(void) {$n" &
-        CommonMainBody & "}$n"
+    PreMainBody =
+      "\tsystemDatInit();$n" &
+      "\tsystemInit();$n" &
+      "$1" &
+      "$2" &
+      "$3" &
+      "$4"
+
+    MainProcs =
+      "\tPreMain();$n" &
+      "\tNimMain();$n"
+    
+    MainProcsWithResult =
+      MainProcs & "\treturn nim_program_result;$n"
+
+    PosixNimMain =
+      "int cmdCount;$n" &
+      "char** cmdLine;$n" &
+      "char** gEnv;$n" &
+      "N_CDECL(void, NimMain)(void) {$n$1}$n"
+  
     PosixCMain = "int main(int argc, char** args, char** env) {$n" &
-        "\tcmdLine = args;$n" & "\tcmdCount = argc;$n" & "\tgEnv = env;$n" &
-        "\tNimMain();$n" & "\treturn nim_program_result;$n" & "}$n"
+      "\tcmdLine = args;$n" & "\tcmdCount = argc;$n" & "\tgEnv = env;$n" &
+      MainProcsWithResult &
+      "}$n"
+  
     StandaloneCMain = "int main(void) {$n" &
-        "\tNimMain();$n" & 
-        "\treturn 0;$n" & "}$n"
-    WinNimMain = "N_CDECL(void, NimMain)(void) {$n" &
-        CommonMainBody & "}$n"
+      MainProcs &
+      "\treturn 0;$n" & "}$n"
+    
+    WinNimMain = "N_CDECL(void, NimMain)(void) {$n$1}$n"
+    
     WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" &
-        "                        HINSTANCE hPrevInstance, $n" &
-        "                        LPSTR lpCmdLine, int nCmdShow) {$n" &
-        "\tNimMain();$n" & "\treturn nim_program_result;$n" & "}$n"
-    WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n" &
-        CommonMainBody & "}$n"
-    WinCDllMain = 
-        "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $n" &
-        "                    LPVOID lpvReserved) {$n" &
-          "\tif(fwdreason == DLL_PROCESS_ATTACH) NimMain();$n" &
-        "\treturn 1;$n" & "}$n"
+      "                        HINSTANCE hPrevInstance, $n" &
+      "                        LPSTR lpCmdLine, int nCmdShow) {$n" &
+      MainProcsWithResult & "}$n"
+  
+    WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n$1}$n"
+
+    WinCDllMain =
+      "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $n" &
+      "                    LPVOID lpvReserved) {$n" &
+      "\tif(fwdreason == DLL_PROCESS_ATTACH) {" & MainProcs & "}$n" &
+      "\treturn 1;$n}$n"
+
     PosixNimDllMain = WinNimDllMain
-    PosixCDllMain = 
-        "void NIM_POSIX_INIT NimMainInit(void) {$n" &
-        "\tNimMain();$n}$n"
+    
+    PosixCDllMain =
+      "void NIM_POSIX_INIT NimMainInit(void) {$n" &
+      MainProcs &
+      "}$n"
+
   var nimMain, otherMain: TFormatStr
   if platform.targetOS == osWindows and
       gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}: 
@@ -1008,8 +1024,10 @@ proc genMainProc(m: BModule) =
                               platform.targetOS == osStandalone: "".toRope
                             else: ropecg(m, "\t#initStackBottom();$n")
   inc(m.labels)
-  appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall,
-        gBreakpoints, mainModInit, toRope(m.labels)])
+  appcg(m, m.s[cfsProcs], "void PreMain() {$n" & PreMainBody & "}$n", [
+    mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit])
+
+  appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)])
   if optNoMain notin gGlobalOptions:
     appcg(m, m.s[cfsProcs], otherMain, [])
 
@@ -1030,10 +1048,14 @@ proc registerModuleToMain(m: PSym) =
                       "declare void $1() noinline$N", [init])
   appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
                       "declare void $1() noinline$N", [datInit])
-  if not (sfSystemModule in m.flags):
-    appff(mainModInit, "\t$1();$n", "call void ()* $1$n", [init])
+  if sfSystemModule notin m.flags:
     appff(mainDatInit, "\t$1();$n", "call void ()* $1$n", [datInit])
-  
+    let initCall = ropeff("\t$1();$n", "call void ()* $1$n", [init])
+    if sfMainModule in m.flags:
+      app(mainModInit, initCall)
+    else:
+      app(otherModsInit, initCall)
+    
 proc genInitCode(m: BModule) = 
   var initname = getInitName(m.module)
   var prc = ropeff("N_NOINLINE(void, $1)(void) {$n", 
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index d72f9fa4d..9cd2c0d87 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -114,7 +114,8 @@ type
     injectStmt*: PRope
 
 var
-  mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
+  mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: PRope
+    # varuious parts of the main module
   gMapping*: PRope             # the generated mapping file (if requested)
   gModules*: seq[BModule] = @[] # list of all compiled modules
   gForwardedProcsCounter*: int = 0