fixes #1888
This commit is contained in:
parent
b34bd3b163
commit
c6398d408d
9 changed files with 107 additions and 81 deletions
|
|
@ -551,12 +551,7 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
|||
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||
|
||||
proc getRaiseFrmt(p: BProc): string =
|
||||
if p.module.compileToCpp:
|
||||
result = "throw NimException($1, $2);$n"
|
||||
elif getCompilerProc("Exception") != nil:
|
||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
||||
else:
|
||||
result = "#raiseException((#E_Base*)$1, $2);$n"
|
||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
||||
|
||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||
if p.inExceptBlock > 0:
|
||||
|
|
@ -797,11 +792,8 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
# finallyPart();
|
||||
if not isEmptyType(t.typ) and d.k == locNone:
|
||||
getTemp(p, t.typ, d)
|
||||
var
|
||||
exc: Rope
|
||||
i, length, blen: int
|
||||
genLineDir(p, t)
|
||||
exc = getTempName()
|
||||
let exc = getTempName()
|
||||
if getCompilerProc("Exception") != nil:
|
||||
discard cgsym(p.module, "Exception")
|
||||
else:
|
||||
|
|
@ -809,20 +801,23 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
add(p.nestedTryStmts, t)
|
||||
startBlock(p, "try {$n")
|
||||
expr(p, t.sons[0], d)
|
||||
length = sonsLen(t)
|
||||
let length = sonsLen(t)
|
||||
endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
|
||||
if optStackTrace in p.options:
|
||||
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR);$n")
|
||||
inc p.inExceptBlock
|
||||
i = 1
|
||||
var i = 1
|
||||
var catchAllPresent = false
|
||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
||||
blen = sonsLen(t.sons[i])
|
||||
let blen = sonsLen(t.sons[i])
|
||||
if i > 1: addf(p.s(cpsStmts), "else ", [])
|
||||
if blen == 1:
|
||||
# general except section:
|
||||
catchAllPresent = true
|
||||
exprBlock(p, t.sons[i].sons[0], d)
|
||||
startBlock(p)
|
||||
expr(p, t.sons[i].sons[0], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
endBlock(p)
|
||||
else:
|
||||
var orExpr: Rope = nil
|
||||
for j in countup(0, blen - 2):
|
||||
|
|
@ -832,7 +827,10 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
"#isObj($1.exp->m_type, $2)",
|
||||
[exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
||||
lineF(p, cpsStmts, "if ($1) ", [orExpr])
|
||||
exprBlock(p, t.sons[i].sons[blen-1], d)
|
||||
startBlock(p)
|
||||
expr(p, t.sons[i].sons[blen-1], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
endBlock(p)
|
||||
inc(i)
|
||||
|
||||
# reraise the exception if there was no catch all
|
||||
|
|
|
|||
|
|
@ -214,41 +214,49 @@ proc raiseExceptionAux(e: ref Exception) =
|
|||
if not localRaiseHook(e): return
|
||||
if globalRaiseHook != nil:
|
||||
if not globalRaiseHook(e): return
|
||||
if excHandler != nil:
|
||||
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
||||
pushCurrentException(e)
|
||||
c_longjmp(excHandler.context, 1)
|
||||
elif e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
when hasSomeStackTrace:
|
||||
var buf = newStringOfCap(2000)
|
||||
if isNil(e.trace): rawWriteStackTrace(buf)
|
||||
else: add(buf, e.trace)
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
add(buf, $e.name)
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
when defined(cpp):
|
||||
if e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
# ugly, but avoids heap allocations :-)
|
||||
template xadd(buf, s, slen: expr) =
|
||||
if L + slen < high(buf):
|
||||
copyMem(addr(buf[L]), cstring(s), slen)
|
||||
inc L, slen
|
||||
template add(buf, s: expr) =
|
||||
xadd(buf, s, s.len)
|
||||
var buf: array [0..2000, char]
|
||||
var L = 0
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, c_strlen(e.name))
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
quitOrDebug()
|
||||
pushCurrentException(e)
|
||||
{.emit: "throw NimException(`e`, `e`->name);".}
|
||||
else:
|
||||
if excHandler != nil:
|
||||
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
||||
pushCurrentException(e)
|
||||
c_longjmp(excHandler.context, 1)
|
||||
elif e[] of OutOfMemError:
|
||||
showErrorMessage(e.name)
|
||||
quitOrDebug()
|
||||
else:
|
||||
when hasSomeStackTrace:
|
||||
var buf = newStringOfCap(2000)
|
||||
if isNil(e.trace): rawWriteStackTrace(buf)
|
||||
else: add(buf, e.trace)
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
add(buf, $e.name)
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
else:
|
||||
# ugly, but avoids heap allocations :-)
|
||||
template xadd(buf, s, slen: expr) =
|
||||
if L + slen < high(buf):
|
||||
copyMem(addr(buf[L]), cstring(s), slen)
|
||||
inc L, slen
|
||||
template add(buf, s: expr) =
|
||||
xadd(buf, s, s.len)
|
||||
var buf: array [0..2000, char]
|
||||
var L = 0
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, c_strlen(e.name))
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
quitOrDebug()
|
||||
|
||||
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
||||
e.name = ename
|
||||
|
|
|
|||
17
tests/cpp/tcppraise.nim
Normal file
17
tests/cpp/tcppraise.nim
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
discard """
|
||||
cmd: "nim cpp $file"
|
||||
output: '''foo
|
||||
bar
|
||||
Need odd and >= 3 digits##
|
||||
baz'''
|
||||
"""
|
||||
|
||||
# bug #1888
|
||||
echo "foo"
|
||||
try:
|
||||
echo "bar"
|
||||
raise newException(ValueError, "Need odd and >= 3 digits")
|
||||
# echo "baz"
|
||||
except ValueError:
|
||||
echo getCurrentExceptionMsg(), "##"
|
||||
echo "baz"
|
||||
|
|
@ -5,20 +5,20 @@ discard """
|
|||
|
||||
# First variety
|
||||
try:
|
||||
raise newException(EOS, "Problem")
|
||||
except EOS:
|
||||
raise newException(OSError, "Problem")
|
||||
except OSError:
|
||||
for y in [1, 2, 3]:
|
||||
discard
|
||||
try:
|
||||
discard
|
||||
except EOS:
|
||||
except OSError:
|
||||
discard
|
||||
echo "1"
|
||||
|
||||
# Second Variety
|
||||
try:
|
||||
raise newException(EOS, "Problem")
|
||||
except EOS:
|
||||
raise newException(OSError, "Problem")
|
||||
except OSError:
|
||||
for y in [1, 2, 3]:
|
||||
discard
|
||||
for y in [1, 2, 3]:
|
||||
|
|
@ -28,8 +28,8 @@ echo "2"
|
|||
|
||||
# Third Variety
|
||||
try:
|
||||
raise newException(EOS, "Problem")
|
||||
except EOS:
|
||||
raise newException(OSError, "Problem")
|
||||
except OSError:
|
||||
block:
|
||||
break
|
||||
|
||||
|
|
@ -38,8 +38,8 @@ echo "3"
|
|||
# Fourth Variety
|
||||
block:
|
||||
try:
|
||||
raise newException(EOS, "Problem")
|
||||
except EOS:
|
||||
raise newException(OSError, "Problem")
|
||||
except OSError:
|
||||
break
|
||||
|
||||
echo "4"
|
||||
|
|
@ -5,8 +5,8 @@ discard """
|
|||
# Test inheritance for exception matching:
|
||||
|
||||
try:
|
||||
raise newException(EOS, "dummy message")
|
||||
except E_Base:
|
||||
raise newException(OSError, "dummy message")
|
||||
except Exception:
|
||||
echo "caught!"
|
||||
except:
|
||||
echo "wtf!?"
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ proc main: int =
|
|||
try: #A
|
||||
try: #B
|
||||
if raiseEx:
|
||||
raise newException(EOS, "")
|
||||
raise newException(OSError, "")
|
||||
return 3
|
||||
finally: #B
|
||||
echo "B1"
|
||||
if returnB:
|
||||
return 2
|
||||
echo "B2"
|
||||
except EOS: #A
|
||||
except OSError: #A
|
||||
echo "catch"
|
||||
finally: #A
|
||||
echo "A1"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ discard """
|
|||
|
||||
proc test1() =
|
||||
|
||||
finally: echo "A"
|
||||
defer: echo "A"
|
||||
|
||||
try:
|
||||
raise newException(OSError, "Problem")
|
||||
|
|
@ -19,7 +19,7 @@ test1()
|
|||
|
||||
proc test2() =
|
||||
|
||||
finally: echo "B"
|
||||
defer: echo "B"
|
||||
|
||||
try:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ success'''
|
|||
"""
|
||||
|
||||
type
|
||||
ESomething = object of E_Base
|
||||
ESomeOtherErr = object of E_Base
|
||||
ESomething = object of Exception
|
||||
ESomeOtherErr = object of Exception
|
||||
|
||||
proc genErrors(s: string) =
|
||||
if s == "error!":
|
||||
|
|
@ -17,7 +17,7 @@ proc foo() =
|
|||
var i = 0
|
||||
try:
|
||||
inc i
|
||||
onRaise(proc (e: ref E_Base): bool =
|
||||
onRaise(proc (e: ref Exception): bool =
|
||||
echo "i: ", i)
|
||||
genErrors("errssor!")
|
||||
except ESomething:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ News
|
|||
====
|
||||
|
||||
..
|
||||
2015-03-01 Version 0.10.4 released
|
||||
2015-03-01 Version 0.11.0 released
|
||||
==================================
|
||||
|
||||
|
||||
|
|
@ -131,6 +131,9 @@ News
|
|||
|
||||
- A single underscore can now be used to discard values when unpacking tuples.
|
||||
- ``marshal.$$`` and ``marshal.to`` can be executed at compile-time.
|
||||
- Interoperability with C++ improved tremendously; C++'s templates and
|
||||
operators can be wrapped directly. See `this <nimc.html#ImportCpp-pragma>`_
|
||||
for more information.
|
||||
|
||||
|
||||
Library additions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue