summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgstmts.nim73
1 files changed, 38 insertions, 35 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 96f5b53a7..510dbfc18 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -157,6 +157,39 @@ proc genState(p: BProc, n: PNode) =
   elif n0.kind == nkStrLit:
     linefmt(p, cpsStmts, "$1: ;$n", n0.strVal.rope)
 
+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 = newSeq[tuple[n: PNode, inExcept: bool]](0)
+
+  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 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.
+    stack.add(tryStmt)
+
+    # Find finally-stmt for this try-stmt
+    # and generate a copy of its sons
+    var finallyStmt = lastSon(tryStmt.n)
+    if finallyStmt.kind == nkFinally:
+      genStmts(p, finallyStmt.sons[0])
+
+  # push old elements again:
+  for i in countdown(howManyTrys-1, 0):
+    p.nestedTryStmts.add(stack[i])
+
+  if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
+    # Pop exceptions that was handled by the
+    # except-blocks we are in
+    for i in countdown(howManyExcepts-1, 0):
+      linefmt(p, cpsStmts, "#popCurrentException();$n")
+
 proc genGotoState(p: BProc, n: PNode) =
   # we resist the temptation to translate it into duff's device as it later
   # will be translated into computed gotos anyway for GCC at least:
@@ -167,7 +200,11 @@ proc genGotoState(p: BProc, n: PNode) =
   initLocExpr(p, n.sons[0], a)
   lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)])
   p.beforeRetNeeded = true
-  lineF(p, cpsStmts, "case -1: goto BeforeRet_;$n", [])
+  lineF(p, cpsStmts, "case -1:$n", [])
+  blockLeaveActions(p,
+    howManyTrys    = p.nestedTryStmts.len,
+    howManyExcepts = p.inExceptBlockLen)
+  lineF(p, cpsStmts, " goto BeforeRet_;$n", [])
   var statesCounter = lastOrd(n.sons[0].typ)
   if n.len >= 2 and n[1].kind == nkIntLit:
     statesCounter = n[1].intVal
@@ -328,40 +365,6 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
     else: internalError(n.info, "genIf()")
   if sonsLen(n) > 1: fixLabel(p, lend)
 
-
-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 = newSeq[tuple[n: PNode, inExcept: bool]](0)
-
-  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 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.
-    stack.add(tryStmt)
-
-    # Find finally-stmt for this try-stmt
-    # and generate a copy of its sons
-    var finallyStmt = lastSon(tryStmt.n)
-    if finallyStmt.kind == nkFinally:
-      genStmts(p, finallyStmt.sons[0])
-
-  # push old elements again:
-  for i in countdown(howManyTrys-1, 0):
-    p.nestedTryStmts.add(stack[i])
-
-  if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
-    # Pop exceptions that was handled by the
-    # except-blocks we are in
-    for i in countdown(howManyExcepts-1, 0):
-      linefmt(p, cpsStmts, "#popCurrentException();$n")
-
 proc genReturnStmt(p: BProc, t: PNode) =
   if nfPreventCg in t.flags: return
   p.beforeRetNeeded = true