summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-06-07 23:15:56 +0200
committerGitHub <noreply@github.com>2018-06-07 23:15:56 +0200
commitf99acdb07584d2c4c5eb1f22d998d97bcd823357 (patch)
treec7e617cc74da11ae8e2c97ef59a68eaa2f53c020
parent2b391ef9614ed9c982bb963e61be219bbbb6fc43 (diff)
parent29a01da90f395e32fdb5ae88949010700b2c427e (diff)
downloadNim-f99acdb07584d2c4c5eb1f22d998d97bcd823357.tar.gz
Merge pull request #7986 from yglukhov/fix-7982
Fixes #7982
-rw-r--r--compiler/ccgstmts.nim13
-rw-r--r--compiler/cgendata.nim2
-rw-r--r--compiler/pragmas.nim4
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.}")