diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-06-07 23:15:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-07 23:15:56 +0200 |
commit | f99acdb07584d2c4c5eb1f22d998d97bcd823357 (patch) | |
tree | c7e617cc74da11ae8e2c97ef59a68eaa2f53c020 | |
parent | 2b391ef9614ed9c982bb963e61be219bbbb6fc43 (diff) | |
parent | 29a01da90f395e32fdb5ae88949010700b2c427e (diff) | |
download | Nim-f99acdb07584d2c4c5eb1f22d998d97bcd823357.tar.gz |
Merge pull request #7986 from yglukhov/fix-7982
Fixes #7982
-rw-r--r-- | compiler/ccgstmts.nim | 13 | ||||
-rw-r--r-- | compiler/cgendata.nim | 2 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 |
3 files changed, 15 insertions, 4 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 91a3add70..f99ee9270 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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): diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index ce3fc2f90..843677654 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -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]] diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index de98a5e42..d3fa506cb 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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.}") |