This commit is contained in:
Araq 2015-04-27 23:11:36 +02:00
commit c6398d408d
9 changed files with 107 additions and 81 deletions

View file

@ -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

View file

@ -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
View 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"

View file

@ -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"

View file

@ -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!?"

View file

@ -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"

View file

@ -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

View file

@ -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:

View file

@ -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