This commit is contained in:
Yuriy Glukhov
2018-06-07 16:38:47 +03:00
parent e67eddc91b
commit 29a01da90f
3 changed files with 15 additions and 4 deletions

View File

@@ -775,6 +775,13 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) =
else:
genOrdinalCase(p, t, d)
proc genRestoreFrameAfterException(p: BProc) =
if optStackTrace in p.module.config.options:
if not p.hasCurFramePointer:
p.hasCurFramePointer = true
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", []))
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", []))
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n")
proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
# code to generate:
@@ -794,8 +801,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
# finallyPart();
template genExceptBranchBody(body: PNode) {.dirty.} =
if optStackTrace in p.options:
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n")
genRestoreFrameAfterException(p)
expr(p, body, d)
if not isEmptyType(t.typ) and d.k == locNone:
@@ -898,8 +904,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
endBlock(p)
startBlock(p, "else {$n")
linefmt(p, cpsStmts, "#popSafePoint();$n")
if optStackTrace in p.options:
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n")
genRestoreFrameAfterException(p)
p.nestedTryStmts[^1].inExcept = true
var i = 1
while (i < length) and (t.sons[i].kind == nkExceptBranch):

View File

@@ -69,6 +69,8 @@ type
prc*: PSym # the Nim proc that this C proc belongs to
beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed
threadVarAccessed*: bool # true if the proc already accessed some threadvar
hasCurFramePointer*: bool # true if _nimCurFrame var needed to recover after
# exception is generated
lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements
currLineInfo*: TLineInfo # AST codegen will make this superfluous
nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]]

View File

@@ -374,6 +374,10 @@ proc processPush(c: PContext, n: PNode, start: int) =
x.otherPragmas.add n.sons[i]
#localError(c.config, n.info, errOptionExpected)
# If stacktrace is disabled globally we should not enable it
if optStackTrace notin c.optionStack[0].options:
c.config.options.excl(optStackTrace)
proc processPop(c: PContext, n: PNode) =
if c.optionStack.len <= 1:
localError(c.config, n.info, "{.pop.} without a corresponding {.push.}")