More robust implementation for finding the beginning of the stack.
This patch inserts an extra stack frame above the function that calls the actual Nimrod code and ensures that a reference to this frame is stored as the stack bottom.
This commit is contained in:
parent
dcf1425eb9
commit
15734009ca
2 changed files with 23 additions and 8 deletions
|
|
@ -954,8 +954,7 @@ proc genMainProc(m: BModule) =
|
||||||
"\tsystemInit();$N" &
|
"\tsystemInit();$N" &
|
||||||
"$1" &
|
"$1" &
|
||||||
"$2" &
|
"$2" &
|
||||||
"$3" &
|
"$3"
|
||||||
"$4"
|
|
||||||
|
|
||||||
MainProcs =
|
MainProcs =
|
||||||
"\tNimMain();$N"
|
"\tNimMain();$N"
|
||||||
|
|
@ -963,10 +962,19 @@ proc genMainProc(m: BModule) =
|
||||||
MainProcsWithResult =
|
MainProcsWithResult =
|
||||||
MainProcs & "\treturn nim_program_result;$N"
|
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 =
|
NimMainBody =
|
||||||
"N_CDECL(void, NimMain)(void) {$N" &
|
"N_CDECL(void, NimMainInner)(void) {$N" &
|
||||||
"\tPreMain();$N" &
|
"\tPreMain();$N" &
|
||||||
"$1" &
|
"$1" &
|
||||||
|
"}$N$N" &
|
||||||
|
"N_CDECL(void, NimMain)(void) {$N" &
|
||||||
|
"\tvoid (*volatile inner)();$N" &
|
||||||
|
"\tinner = NimMainInner;$N" &
|
||||||
|
"$2" &
|
||||||
|
"\t(*inner)();$N" &
|
||||||
"}$N$N"
|
"}$N$N"
|
||||||
|
|
||||||
PosixNimMain =
|
PosixNimMain =
|
||||||
|
|
@ -1034,14 +1042,15 @@ proc genMainProc(m: BModule) =
|
||||||
if optEndb in gOptions:
|
if optEndb in gOptions:
|
||||||
gBreakpoints.app(m.genFilenames)
|
gBreakpoints.app(m.genFilenames)
|
||||||
|
|
||||||
let initStackBottomCall = if emulatedThreadVars() or
|
let initStackBottomCall =
|
||||||
platform.targetOS == osStandalone: "".toRope
|
if emulatedThreadVars() or
|
||||||
else: ropecg(m, "\t#initStackBottom();$N")
|
platform.targetOS == osStandalone: "".toRope
|
||||||
|
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
|
||||||
inc(m.labels)
|
inc(m.labels)
|
||||||
appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [
|
appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [
|
||||||
mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit])
|
mainDatInit, gBreakpoints, otherModsInit])
|
||||||
|
|
||||||
appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)])
|
appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)])
|
||||||
if optNoMain notin gGlobalOptions:
|
if optNoMain notin gGlobalOptions:
|
||||||
appcg(m, m.s[cfsProcs], otherMain, [])
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2115,6 +2115,12 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
locals = addr(locals)
|
locals = addr(locals)
|
||||||
setStackBottom(locals)
|
setStackBottom(locals)
|
||||||
|
|
||||||
|
proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} =
|
||||||
|
# We need to keep initStackBottom around for now to avoid
|
||||||
|
# bootstrapping problems.
|
||||||
|
when defined(setStackBottom):
|
||||||
|
setStackBottom(locals)
|
||||||
|
|
||||||
var
|
var
|
||||||
strDesc: TNimType
|
strDesc: TNimType
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue