summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorReimer Behrends <behrends@gmail.com>2014-08-14 03:09:39 +0200
committerReimer Behrends <behrends@gmail.com>2014-08-14 03:09:39 +0200
commitd59b9a21689d82d424b7be0d699ccbf3ba538d31 (patch)
treedda7f08c4b71dd92282fa6ff1932c1e1597af605
parenta772105e7d1662cfc3bf4ce382349d4ea4b72a30 (diff)
downloadNim-d59b9a21689d82d424b7be0d699ccbf3ba538d31.tar.gz
Fix stack bottom initialization for non-main modules.
Because PreMain() was now called before the new stack bottom
initialization, it still relied on the old version of initStackBottom(),
which may not handle the top few words of the stack correctly. This
patch also sets the stack bottom in PreMain() using the new approach.
-rw-r--r--compiler/cgen.nim22
1 files changed, 15 insertions, 7 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 112a2af34..2d3831a15 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -949,12 +949,23 @@ proc genFilenames(m: BModule): PRope =
 
 proc genMainProc(m: BModule) =
   const 
+    # The use of a volatile function pointer to call Pre/NimMainInner
+    # prevents inlining of the NimMainInner function and dependent
+    # functions, which might otherwise merge their stack frames.
     PreMainBody =
-      "\tsystemDatInit();$N" &
+      "void PreMainInner() {$N" &
       "\tsystemInit();$N" &
       "$1" &
       "$2" &
-      "$3"
+      "$3" &
+      "}$N$N" &
+      "void PreMain() {$N" &
+      "\tvoid (*volatile inner)();$N" &
+      "\tsystemDatInit();$N" &
+      "\tinner = PreMainInner;$N" &
+      "$4" &
+      "\t(*inner)();$N" &
+      "}$N$N"
 
     MainProcs =
       "\tNimMain();$N"
@@ -962,9 +973,6 @@ proc genMainProc(m: BModule) =
     MainProcsWithResult =
       MainProcs & "\treturn nim_program_result;$N"
 
-    # The use of a volatile function pointer to call NimMainInner
-    # prevents inlining of the NimMainInner function and dependent
-    # functions, which might otherwise merge their stack frames.
     NimMainBody =
       "N_CDECL(void, NimMainInner)(void) {$N" &
         "$1" &
@@ -1047,8 +1055,8 @@ proc genMainProc(m: BModule) =
       platform.targetOS == osStandalone: "".toRope
     else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
   inc(m.labels)
-  appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [
-    mainDatInit, gBreakpoints, otherModsInit])
+  appcg(m, m.s[cfsProcs], PreMainBody, [
+    mainDatInit, gBreakpoints, otherModsInit, initStackBottomCall])
 
   appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)])
   if optNoMain notin gGlobalOptions: