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])
|
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||||
|
|
||||||
proc getRaiseFrmt(p: BProc): string =
|
proc getRaiseFrmt(p: BProc): string =
|
||||||
if p.module.compileToCpp:
|
result = "#raiseException((#Exception*)$1, $2);$n"
|
||||||
result = "throw NimException($1, $2);$n"
|
|
||||||
elif getCompilerProc("Exception") != nil:
|
|
||||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
|
||||||
else:
|
|
||||||
result = "#raiseException((#E_Base*)$1, $2);$n"
|
|
||||||
|
|
||||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
if p.inExceptBlock > 0:
|
if p.inExceptBlock > 0:
|
||||||
|
|
@ -797,11 +792,8 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
# finallyPart();
|
# finallyPart();
|
||||||
if not isEmptyType(t.typ) and d.k == locNone:
|
if not isEmptyType(t.typ) and d.k == locNone:
|
||||||
getTemp(p, t.typ, d)
|
getTemp(p, t.typ, d)
|
||||||
var
|
|
||||||
exc: Rope
|
|
||||||
i, length, blen: int
|
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
exc = getTempName()
|
let exc = getTempName()
|
||||||
if getCompilerProc("Exception") != nil:
|
if getCompilerProc("Exception") != nil:
|
||||||
discard cgsym(p.module, "Exception")
|
discard cgsym(p.module, "Exception")
|
||||||
else:
|
else:
|
||||||
|
|
@ -809,20 +801,23 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
add(p.nestedTryStmts, t)
|
add(p.nestedTryStmts, t)
|
||||||
startBlock(p, "try {$n")
|
startBlock(p, "try {$n")
|
||||||
expr(p, t.sons[0], d)
|
expr(p, t.sons[0], d)
|
||||||
length = sonsLen(t)
|
let length = sonsLen(t)
|
||||||
endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
|
endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
|
||||||
if optStackTrace in p.options:
|
if optStackTrace in p.options:
|
||||||
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR);$n")
|
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR);$n")
|
||||||
inc p.inExceptBlock
|
inc p.inExceptBlock
|
||||||
i = 1
|
var i = 1
|
||||||
var catchAllPresent = false
|
var catchAllPresent = false
|
||||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
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 i > 1: addf(p.s(cpsStmts), "else ", [])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
catchAllPresent = true
|
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:
|
else:
|
||||||
var orExpr: Rope = nil
|
var orExpr: Rope = nil
|
||||||
for j in countup(0, blen - 2):
|
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)",
|
"#isObj($1.exp->m_type, $2)",
|
||||||
[exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
[exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
||||||
lineF(p, cpsStmts, "if ($1) ", [orExpr])
|
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)
|
inc(i)
|
||||||
|
|
||||||
# reraise the exception if there was no catch all
|
# reraise the exception if there was no catch all
|
||||||
|
|
|
||||||
|
|
@ -214,41 +214,49 @@ proc raiseExceptionAux(e: ref Exception) =
|
||||||
if not localRaiseHook(e): return
|
if not localRaiseHook(e): return
|
||||||
if globalRaiseHook != nil:
|
if globalRaiseHook != nil:
|
||||||
if not globalRaiseHook(e): return
|
if not globalRaiseHook(e): return
|
||||||
if excHandler != nil:
|
when defined(cpp):
|
||||||
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
if e[] of OutOfMemError:
|
||||||
pushCurrentException(e)
|
showErrorMessage(e.name)
|
||||||
c_longjmp(excHandler.context, 1)
|
quitOrDebug()
|
||||||
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:
|
else:
|
||||||
# ugly, but avoids heap allocations :-)
|
pushCurrentException(e)
|
||||||
template xadd(buf, s, slen: expr) =
|
{.emit: "throw NimException(`e`, `e`->name);".}
|
||||||
if L + slen < high(buf):
|
else:
|
||||||
copyMem(addr(buf[L]), cstring(s), slen)
|
if excHandler != nil:
|
||||||
inc L, slen
|
if not excHandler.hasRaiseAction or excHandler.raiseAction(e):
|
||||||
template add(buf, s: expr) =
|
pushCurrentException(e)
|
||||||
xadd(buf, s, s.len)
|
c_longjmp(excHandler.context, 1)
|
||||||
var buf: array [0..2000, char]
|
elif e[] of OutOfMemError:
|
||||||
var L = 0
|
showErrorMessage(e.name)
|
||||||
add(buf, "Error: unhandled exception: ")
|
quitOrDebug()
|
||||||
if not isNil(e.msg): add(buf, e.msg)
|
else:
|
||||||
add(buf, " [")
|
when hasSomeStackTrace:
|
||||||
xadd(buf, e.name, c_strlen(e.name))
|
var buf = newStringOfCap(2000)
|
||||||
add(buf, "]\n")
|
if isNil(e.trace): rawWriteStackTrace(buf)
|
||||||
showErrorMessage(buf)
|
else: add(buf, e.trace)
|
||||||
quitOrDebug()
|
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.} =
|
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
||||||
e.name = ename
|
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
|
# First variety
|
||||||
try:
|
try:
|
||||||
raise newException(EOS, "Problem")
|
raise newException(OSError, "Problem")
|
||||||
except EOS:
|
except OSError:
|
||||||
for y in [1, 2, 3]:
|
for y in [1, 2, 3]:
|
||||||
discard
|
discard
|
||||||
try:
|
try:
|
||||||
discard
|
discard
|
||||||
except EOS:
|
except OSError:
|
||||||
discard
|
discard
|
||||||
echo "1"
|
echo "1"
|
||||||
|
|
||||||
# Second Variety
|
# Second Variety
|
||||||
try:
|
try:
|
||||||
raise newException(EOS, "Problem")
|
raise newException(OSError, "Problem")
|
||||||
except EOS:
|
except OSError:
|
||||||
for y in [1, 2, 3]:
|
for y in [1, 2, 3]:
|
||||||
discard
|
discard
|
||||||
for y in [1, 2, 3]:
|
for y in [1, 2, 3]:
|
||||||
|
|
@ -28,8 +28,8 @@ echo "2"
|
||||||
|
|
||||||
# Third Variety
|
# Third Variety
|
||||||
try:
|
try:
|
||||||
raise newException(EOS, "Problem")
|
raise newException(OSError, "Problem")
|
||||||
except EOS:
|
except OSError:
|
||||||
block:
|
block:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -38,8 +38,8 @@ echo "3"
|
||||||
# Fourth Variety
|
# Fourth Variety
|
||||||
block:
|
block:
|
||||||
try:
|
try:
|
||||||
raise newException(EOS, "Problem")
|
raise newException(OSError, "Problem")
|
||||||
except EOS:
|
except OSError:
|
||||||
break
|
break
|
||||||
|
|
||||||
echo "4"
|
echo "4"
|
||||||
|
|
@ -5,8 +5,8 @@ discard """
|
||||||
# Test inheritance for exception matching:
|
# Test inheritance for exception matching:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raise newException(EOS, "dummy message")
|
raise newException(OSError, "dummy message")
|
||||||
except E_Base:
|
except Exception:
|
||||||
echo "caught!"
|
echo "caught!"
|
||||||
except:
|
except:
|
||||||
echo "wtf!?"
|
echo "wtf!?"
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ proc main: int =
|
||||||
try: #A
|
try: #A
|
||||||
try: #B
|
try: #B
|
||||||
if raiseEx:
|
if raiseEx:
|
||||||
raise newException(EOS, "")
|
raise newException(OSError, "")
|
||||||
return 3
|
return 3
|
||||||
finally: #B
|
finally: #B
|
||||||
echo "B1"
|
echo "B1"
|
||||||
if returnB:
|
if returnB:
|
||||||
return 2
|
return 2
|
||||||
echo "B2"
|
echo "B2"
|
||||||
except EOS: #A
|
except OSError: #A
|
||||||
echo "catch"
|
echo "catch"
|
||||||
finally: #A
|
finally: #A
|
||||||
echo "A1"
|
echo "A1"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ discard """
|
||||||
|
|
||||||
proc test1() =
|
proc test1() =
|
||||||
|
|
||||||
finally: echo "A"
|
defer: echo "A"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raise newException(OSError, "Problem")
|
raise newException(OSError, "Problem")
|
||||||
|
|
@ -19,7 +19,7 @@ test1()
|
||||||
|
|
||||||
proc test2() =
|
proc test2() =
|
||||||
|
|
||||||
finally: echo "B"
|
defer: echo "B"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ success'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
ESomething = object of E_Base
|
ESomething = object of Exception
|
||||||
ESomeOtherErr = object of E_Base
|
ESomeOtherErr = object of Exception
|
||||||
|
|
||||||
proc genErrors(s: string) =
|
proc genErrors(s: string) =
|
||||||
if s == "error!":
|
if s == "error!":
|
||||||
|
|
@ -17,7 +17,7 @@ proc foo() =
|
||||||
var i = 0
|
var i = 0
|
||||||
try:
|
try:
|
||||||
inc i
|
inc i
|
||||||
onRaise(proc (e: ref E_Base): bool =
|
onRaise(proc (e: ref Exception): bool =
|
||||||
echo "i: ", i)
|
echo "i: ", i)
|
||||||
genErrors("errssor!")
|
genErrors("errssor!")
|
||||||
except ESomething:
|
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.
|
- A single underscore can now be used to discard values when unpacking tuples.
|
||||||
- ``marshal.$$`` and ``marshal.to`` can be executed at compile-time.
|
- ``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
|
Library additions
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue