diff options
author | Yuriy Glukhov <yuriy.glukhov@gmail.com> | 2018-06-07 16:38:47 +0300 |
---|---|---|
committer | Yuriy Glukhov <yuriy.glukhov@gmail.com> | 2018-06-07 17:17:07 +0300 |
commit | 29a01da90f395e32fdb5ae88949010700b2c427e (patch) | |
tree | 9f7232ed85d2ff698be59ff35523626e017c5583 | |
parent | e67eddc91b5e06039498b337763acf718d436aae (diff) | |
download | Nim-29a01da90f395e32fdb5ae88949010700b2c427e.tar.gz |
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.}") |