summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2016-09-14 17:01:22 +0200
committerAraq <rumpf_a@web.de>2016-09-14 19:59:32 +0200
commitda575bec541b4430610cb0063e3209db9793f008 (patch)
tree0426832029b696cf466f9ab39be49b1697d374be /compiler
parent4f36e95fbddcd23091168c69debdca5ba0c2ed2d (diff)
downloadNim-da575bec541b4430610cb0063e3209db9793f008.tar.gz
VM: 'raises' in an 'except' doesn't cause an endless loop anymore
Diffstat (limited to 'compiler')
-rw-r--r--compiler/vm.nim12
1 files changed, 10 insertions, 2 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 5accf628e..2e2a49db5 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -269,6 +269,7 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame):
         c.currentExceptionA = nil
         # execute the corresponding handler:
         while c.code[pc2].opcode == opcExcept: inc pc2
+        discard f.safePoints.pop
         return (pc2, f)
       inc pc2
       if c.code[pc2].opcode != opcExcept and nextExceptOrFinally >= 0:
@@ -282,7 +283,8 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame):
       pc2 = nextExceptOrFinally
     if c.code[pc2].opcode == opcFinally:
       # execute the corresponding handler, but don't quit walking the stack:
-      return (pc2, f)
+      discard f.safePoints.pop
+      return (pc2+1, f)
     # not the right one:
     discard f.safePoints.pop
 
@@ -964,7 +966,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       # we'll execute in the 'raise' handler
       let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
       inc pc, rbx
-      assert c.code[pc+1].opcode in {opcExcept, opcFinally}
+      while c.code[pc+1].opcode == opcExcept:
+        let rbx = c.code[pc+1].regBx - wordExcess - 1
+        inc pc, rbx
+      #assert c.code[pc+1].opcode in {opcExcept, opcFinally}
+      if c.code[pc+1].opcode != opcFinally:
+        # in an except handler there is no active safe point for the 'try':
+        tos.popSafePoint()
     of opcFinally:
       # just skip it; it's followed by the code we need to execute anyway
       tos.popSafePoint()