diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 10b4b55d0f..b78ad10c43 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1363,16 +1363,25 @@ proc genMainProc(m: BModule) = # 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 = "$N" & + + PreMainVolatileBody = + "\tvoid (*volatile inner)(void);$N" & + "\tinner = PreMainInner;$N" & + "$1" & + "\t(*inner)();$N" + + PreMainNonVolatileBody = + "$1" & + "\tPreMainInner();$N" + + PreMainBodyStart = "$N" & "N_LIB_PRIVATE void PreMainInner(void) {$N" & "$2" & "}$N$N" & PosixCmdLine & - "N_LIB_PRIVATE void PreMain(void) {$N" & - "\tvoid (*volatile inner)(void);$N" & - "\tinner = PreMainInner;$N" & - "$1" & - "\t(*inner)();$N" & + "N_LIB_PRIVATE void PreMain(void) {$N" + + PreMainBodyEnd = "}$N$N" MainProcs = @@ -1385,17 +1394,32 @@ proc genMainProc(m: BModule) = "$1" & "}$N$N" - NimMainProc = - "N_CDECL(void, $5NimMain)(void) {$N" & - "\tvoid (*volatile inner)(void);$N" & - "$4" & - "\tinner = NimMainInner;$N" & - "$2" & - "\t(*inner)();$N" & + NimMainVolatileBody = + "\tvoid (*volatile inner)(void);$N" & + "$4" & + "\tinner = NimMainInner;$N" & + "$2" & + "\t(*inner)();$N" + + NimMainNonVolatileBody = + "$4" & + "$2" & + "\tNimMainInner();$N" + + NimMainProcStart = + "N_CDECL(void, $5NimMain)(void) {$N" + + NimMainProcEnd = "}$N$N" + NimMainProc = NimMainProcStart & NimMainVolatileBody & NimMainProcEnd + + NimSlimMainProc = NimMainProcStart & NimMainNonVolatileBody & NimMainProcEnd + NimMainBody = NimMainInner & NimMainProc + NimSlimMainBody = NimMainInner & NimSlimMainProc + PosixCMain = "int main(int argc, char** args, char** env) {$N" & "\tcmdLine = args;$N" & @@ -1456,10 +1480,13 @@ proc genMainProc(m: BModule) = m.includeHeader("") let initStackBottomCall = - if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope + if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcOrc}: "".rope else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []) inc(m.labels) - appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit]) + if m.config.selectedGC notin {gcNone, gcArc, gcOrc}: + appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit]) + else: + appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainNonVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit]) if m.config.target.targetOS == osWindows and m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}: @@ -1484,9 +1511,14 @@ proc genMainProc(m: BModule) = appcg(m, m.s[cfsProcs], nimMain, [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) else: - const nimMain = NimMainBody - appcg(m, m.s[cfsProcs], nimMain, - [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) + if m.config.selectedGC notin {gcNone, gcArc, gcOrc}: + const nimMain = NimMainBody + appcg(m, m.s[cfsProcs], nimMain, + [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) + else: + const nimMain = NimSlimMainBody + appcg(m, m.s[cfsProcs], nimMain, + [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) if optNoMain notin m.config.globalOptions: if m.config.cppCustomNamespace.len > 0: