ARC related bugfixes and refactorings (#12781)

This commit is contained in:
Andreas Rumpf 2019-12-05 16:59:06 +01:00 • committed by Miran
commit 3fbb3bfd3f
11 changed files with 381 additions and 367 deletions

View file

@ -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,28 +333,13 @@ template unhandled(buf, body) =
else:
body
proc raiseExceptionAux(e: ref Exception) =
if localRaiseHook != nil:
if not localRaiseHook(e): return
if globalRaiseHook != nil:
if not globalRaiseHook(e): return
proc nimLeaveFinally() {.compilerRtl.} =
when defined(cpp) and not defined(noCppExceptions):
if e == currException:
{.emit: "throw;".}
else:
pushCurrentException(e)
raiseCounter.inc
if raiseCounter == 0:
raiseCounter.inc # skip zero at overflow
e.raiseId = raiseCounter
{.emit: "`e`->raise();".}
elif defined(nimQuirky):
pushCurrentException(e)
{.emit: "throw;".}
else:
template e: untyped = currException
if excHandler != nil:
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
pushCurrentException(e)
c_longjmp(excHandler.context, 1)
c_longjmp(excHandler.context, 1)
else:
when hasSomeStackTrace:
var buf = newStringOfCap(2000)
@ -367,6 +353,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 +379,68 @@ proc raiseExceptionAux(e: ref Exception) =
showErrorMessage(tbuf())
quitOrDebug()
proc raiseExceptionEx(e: ref Exception, ename, procname, filename: cstring, line: int) {.compilerRtl.} =
proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
if localRaiseHook != nil:
if not localRaiseHook(e): return
if globalRaiseHook != nil:
if not globalRaiseHook(e): return
when defined(cpp) and not defined(noCppExceptions):
if e == currException:
{.emit: "throw;".}
else:
pushCurrentException(e)
raiseCounter.inc
if raiseCounter == 0:
raiseCounter.inc # skip zero at overflow
e.raiseId = raiseCounter
{.emit: "`e`->raise();".}
elif defined(nimQuirky):
pushCurrentException(e)
else:
if excHandler != nil:
pushCurrentException(e)
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 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.} =