diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-12-05 16:59:06 +0100 |
---|---|---|
committer | Miran <narimiran@disroot.org> | 2019-12-05 16:59:06 +0100 |
commit | 3fbb3bfd3f440c059d6290c12834a38a61da98f2 (patch) | |
tree | b4561f510b23ce4fe2a19e58e15246c5ec5293a0 /lib/system | |
parent | 9b0e874687177af4f758b70994b3a08f963a75cd (diff) | |
download | Nim-3fbb3bfd3f440c059d6290c12834a38a61da98f2.tar.gz |
ARC related bugfixes and refactorings (#12781)
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/excpt.nim | 64 |
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.} = |