summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2018-03-30 02:32:29 +0200
committerAraq <rumpf_a@web.de>2018-03-30 02:32:29 +0200
commita9691aeef513ea20a9b1735f37172a1bd66a80dd (patch)
tree2d0de165d9907a3a8a4b56cea5bb33a3fb201465 /compiler
parent9de05ec3e04e8a2321b29896fe9fa7db4c6e65f3 (diff)
parent325d76b56a5b26ba2d5ce065574eb6ef736eb179 (diff)
downloadNim-a9691aeef513ea20a9b1735f37172a1bd66a80dd.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgstmts.nim40
-rw-r--r--compiler/cgendata.nim9
2 files changed, 23 insertions, 26 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 8a54708ee..f6c4204e8 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -37,6 +37,10 @@ proc isAssignedImmediately(n: PNode): bool {.inline.} =
     return false
   result = true
 
+proc inExceptBlockLen(p: BProc): int = 
+  for x in p.nestedTryStmts:
+    if x.inExcept: result.inc
+
 proc genVarTuple(p: BProc, n: PNode) =
   var tup, field: TLoc
   if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
@@ -96,7 +100,7 @@ proc startBlock(p: BProc, start: FormatStr = "{$n",
   setLen(p.blocks, result + 1)
   p.blocks[result].id = p.labels
   p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
-  p.blocks[result].nestedExceptStmts = p.inExceptBlock.int16
+  p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
 
 proc assignLabel(b: var TBlock): Rope {.inline.} =
   b.label = "LA" & b.id.rope
@@ -344,26 +348,22 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
   # Called by return and break stmts.
   # Deals with issues faced when jumping out of try/except/finally stmts,
 
-  var stack: seq[PNode]
-  newSeq(stack, 0)
+  var stack = newSeq[tuple[n: PNode, inExcept: bool]](0)
 
-  var alreadyPoppedCnt = p.inExceptBlock
   for i in countup(1, howManyTrys):
+    let tryStmt = p.nestedTryStmts.pop
     if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
       # Pop safe points generated by try
-      if alreadyPoppedCnt > 0:
-        dec alreadyPoppedCnt
-      else:
+      if not tryStmt.inExcept:
         linefmt(p, cpsStmts, "#popSafePoint();$n")
 
     # Pop this try-stmt of the list of nested trys
     # so we don't infinite recurse on it in the next step.
-    var tryStmt = p.nestedTryStmts.pop
     stack.add(tryStmt)
 
     # Find finally-stmt for this try-stmt
     # and generate a copy of its sons
-    var finallyStmt = lastSon(tryStmt)
+    var finallyStmt = lastSon(tryStmt.n)
     if finallyStmt.kind == nkFinally:
       genStmts(p, finallyStmt.sons[0])
 
@@ -384,7 +384,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
   if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
   blockLeaveActions(p,
     howManyTrys    = p.nestedTryStmts.len,
-    howManyExcepts = p.inExceptBlock)
+    howManyExcepts = p.inExceptBlockLen)
   if (p.finallySafePoints.len > 0):
     # If we're in a finally block, and we came here by exception
     # consume it before we return.
@@ -567,15 +567,15 @@ proc genBreakStmt(p: BProc, t: PNode) =
   let label = assignLabel(p.blocks[idx])
   blockLeaveActions(p,
     p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts,
-    p.inExceptBlock - p.blocks[idx].nestedExceptStmts)
+    p.inExceptBlockLen - p.blocks[idx].nestedExceptStmts)
   genLineDir(p, t)
   lineF(p, cpsStmts, "goto $1;$n", [label])
 
 proc genRaiseStmt(p: BProc, t: PNode) =
-  if p.inExceptBlock > 0 and p.inExceptBlock == p.nestedTryStmts.len:
+  if p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept:
     # if the current try stmt have a finally block,
     # we must execute it before reraising
-    var finallyBlock = p.nestedTryStmts[p.nestedTryStmts.len - 1].lastSon
+    var finallyBlock = p.nestedTryStmts[^1].n[^1]
     if finallyBlock.kind == nkFinally:
       genSimpleBlock(p, finallyBlock.sons[0])
   if t.sons[0].kind != nkEmpty:
@@ -812,14 +812,14 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
 
   let end_label = getLabel(p)
   discard cgsym(p.module, "Exception")
-  add(p.nestedTryStmts, t)
+  add(p.nestedTryStmts, (t, false))
   startBlock(p, "try {$n")
   expr(p, t[0], d)
   endBlock(p)
 
   var catchAllPresent = false
 
-  inc p.inExceptBlock
+  p.nestedTryStmts[^1].inExcept = true
   for i in 1..<t.len:
     if t[i].kind != nkExceptBranch: break
 
@@ -839,6 +839,8 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
         genExceptBranchBody(t[i][^1])  # exception handler body will duplicated for every type
         endBlock(p)
 
+  discard pop(p.nestedTryStmts)
+
   if not catchAllPresent and t[^1].kind == nkFinally:
     # finally requires catch all presence
     startBlock(p, "catch (...) {$n")
@@ -846,9 +848,6 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
     line(p, cpsStmts, ~"throw;$n")
     endBlock(p)
 
-  dec p.inExceptBlock
-  discard pop(p.nestedTryStmts)
-
   if t[^1].kind == nkFinally:
     genSimpleBlock(p, t[^1][0])
 
@@ -902,7 +901,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
     linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
   startBlock(p, "if ($1.status == 0) {$n", [safePoint])
   var length = sonsLen(t)
-  add(p.nestedTryStmts, t)
+  add(p.nestedTryStmts, (t, false))
   expr(p, t.sons[0], d)
   linefmt(p, cpsStmts, "#popSafePoint();$n")
   endBlock(p)
@@ -910,7 +909,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
   linefmt(p, cpsStmts, "#popSafePoint();$n")
   if optStackTrace in p.options:
     linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n")
-  inc p.inExceptBlock
+  p.nestedTryStmts[^1].inExcept = true
   var i = 1
   while (i < length) and (t.sons[i].kind == nkExceptBranch):
     # bug #4230: avoid false sharing between branches:
@@ -941,7 +940,6 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
       linefmt(p, cpsStmts, "#popCurrentException();$n")
       endBlock(p)
     inc(i)
-  dec p.inExceptBlock
   discard pop(p.nestedTryStmts)
   endBlock(p) # end of else block
   if i < length and t.sons[i].kind == nkFinally:
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index 0f8fa760e..efa346934 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -70,11 +70,10 @@ type
     threadVarAccessed*: bool  # true if the proc already accessed some threadvar
     lastLineInfo*: TLineInfo  # to avoid generating excessive 'nimln' statements
     currLineInfo*: TLineInfo  # AST codegen will make this superfluous
-    nestedTryStmts*: seq[PNode]   # in how many nested try statements we are
-                                  # (the vars must be volatile then)
-    inExceptBlock*: int       # are we currently inside an except block?
-                              # leaving such scopes by raise or by return must
-                              # execute any applicable finally blocks
+    nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]]  
+                              # in how many nested try statements we are
+                              # (the vars must be volatile then)
+                              # bool is true when are in the except part of a try block
     finallySafePoints*: seq[Rope]  # For correctly cleaning up exceptions when
                                    # using return in finally statements
     labels*: Natural          # for generating unique labels in the C proc