summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-12-05 16:59:06 +0100
committerMiran <narimiran@disroot.org>2019-12-05 16:59:06 +0100
commit3fbb3bfd3f440c059d6290c12834a38a61da98f2 (patch)
treeb4561f510b23ce4fe2a19e58e15246c5ec5293a0 /lib/system
parent9b0e874687177af4f758b70994b3a08f963a75cd (diff)
downloadNim-3fbb3bfd3f440c059d6290c12834a38a61da98f2.tar.gz
ARC related bugfixes and refactorings (#12781)
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/excpt.nim64
1 files changed, 56 insertions, 8 deletions
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index ef9a6deaf..6e06b10f8 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -103,19 +103,20 @@ proc pushGcFrame*(s: GcFrame) {.compilerRtl, inl.} =
   gcFramePtr = s
 
 proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} =
-  s.hasRaiseAction = false
   s.prev = excHandler
   excHandler = s
 
 proc popSafePoint {.compilerRtl, inl.} =
   excHandler = excHandler.prev
 
-proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
+proc pushCurrentException(e: sink(ref Exception)) {.compilerRtl, inl.} =
   e.up = currException
   currException = e
+  #showErrorMessage "A"
 
 proc popCurrentException {.compilerRtl, inl.} =
   currException = currException.up
+  #showErrorMessage "B"
 
 proc popCurrentExceptionEx(id: uint) {.compilerRtl.} =
   # in cpp backend exceptions can pop-up in the different order they were raised, example #5628
@@ -332,7 +333,53 @@ template unhandled(buf, body) =
   else:
     body
 
-proc raiseExceptionAux(e: ref Exception) =
+proc nimLeaveFinally() {.compilerRtl.} =
+  when defined(cpp) and not defined(noCppExceptions):
+    {.emit: "throw;".}
+  else:
+    template e: untyped = currException
+    if excHandler != nil:
+      c_longjmp(excHandler.context, 1)
+    else:
+      when hasSomeStackTrace:
+        var buf = newStringOfCap(2000)
+        if e.trace.len == 0: rawWriteStackTrace(buf)
+        else: add(buf, $e.trace)
+        add(buf, "Error: unhandled exception: ")
+        add(buf, e.msg)
+        add(buf, " [")
+        add(buf, $e.name)
+        add(buf, "]\n")
+        unhandled(buf):
+          showErrorMessage(buf)
+          quitOrDebug()
+        `=destroy`(buf)
+      else:
+        # ugly, but avoids heap allocations :-)
+        template xadd(buf, s, slen) =
+          if L + slen < high(buf):
+            copyMem(addr(buf[L]), cstring(s), slen)
+            inc L, slen
+        template add(buf, s) =
+          xadd(buf, s, s.len)
+        var buf: array[0..2000, char]
+        var L = 0
+        if e.trace.len != 0:
+          add(buf, $e.trace) # gc allocation
+        add(buf, "Error: unhandled exception: ")
+        add(buf, e.msg)
+        add(buf, " [")
+        xadd(buf, e.name, e.name.len)
+        add(buf, "]\n")
+        when defined(nimNoArrayToCstringConversion):
+          template tbuf(): untyped = addr buf
+        else:
+          template tbuf(): untyped = buf
+        unhandled(tbuf()):
+          showErrorMessage(tbuf())
+          quitOrDebug()
+
+proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
   if localRaiseHook != nil:
     if not localRaiseHook(e): return
   if globalRaiseHook != nil:
@@ -351,9 +398,8 @@ proc raiseExceptionAux(e: ref Exception) =
     pushCurrentException(e)
   else:
     if excHandler != nil:
-      if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
-        pushCurrentException(e)
-        c_longjmp(excHandler.context, 1)
+      pushCurrentException(e)
+      c_longjmp(excHandler.context, 1)
     else:
       when hasSomeStackTrace:
         var buf = newStringOfCap(2000)
@@ -367,6 +413,7 @@ proc raiseExceptionAux(e: ref Exception) =
         unhandled(buf):
           showErrorMessage(buf)
           quitOrDebug()
+        `=destroy`(buf)
       else:
         # ugly, but avoids heap allocations :-)
         template xadd(buf, s, slen) =
@@ -392,7 +439,8 @@ proc raiseExceptionAux(e: ref Exception) =
           showErrorMessage(tbuf())
           quitOrDebug()
 
-proc raiseExceptionEx(e: ref Exception, ename, procname, filename: cstring, line: int) {.compilerRtl.} =
+proc raiseExceptionEx(e: sink(ref Exception), ename, procname, filename: cstring,
+                      line: int) {.compilerRtl, nodestroy.} =
   if e.name.isNil: e.name = ename
   when hasSomeStackTrace:
     if e.trace.len == 0:
@@ -406,7 +454,7 @@ proc raiseExceptionEx(e: ref Exception, ename, procname, filename: cstring, line
       e.trace.add StackTraceEntry(procname: procname, filename: filename, line: line)
   raiseExceptionAux(e)
 
-proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
+proc raiseException(e: sink(ref Exception), ename: cstring) {.compilerRtl.} =
   raiseExceptionEx(e, ename, nil, nil, 0)
 
 proc reraiseException() {.compilerRtl.} =