summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-04-27 23:11:36 +0200
committerAraq <rumpf_a@web.de>2015-04-27 23:11:59 +0200
commitc6398d408de89672d1df21ee84507978f2320ba8 (patch)
treedc2226977e14097049e6f1e694243dbd781a3c36
parentb34bd3b16371ac05fd293a878976d6dd2326491c (diff)
downloadNim-c6398d408de89672d1df21ee84507978f2320ba8.tar.gz
fixes #1888
-rw-r--r--compiler/ccgstmts.nim28
-rw-r--r--lib/system/excpt.nim86
-rw-r--r--tests/cpp/tcppraise.nim17
-rw-r--r--tests/exception/texceptionbreak.nim20
-rw-r--r--tests/exception/texcsub.nim8
-rw-r--r--tests/exception/tfinally4.nim8
-rw-r--r--tests/exception/tnestedreturn.nim4
-rw-r--r--tests/exception/tonraise.nim8
-rw-r--r--web/news.txt5
9 files changed, 105 insertions, 79 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 1d642db60..6d29b1684 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -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
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 1b3471978..189d52f57 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -58,7 +58,7 @@ proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} =
 proc popSafePoint {.compilerRtl, inl.} =
   excHandler = excHandler.prev
 
-proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = 
+proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} =
   e.parent = currException
   currException = e
 
@@ -69,12 +69,12 @@ proc popCurrentException {.compilerRtl, inl.} =
 const
   nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and
                               not NimStackTrace
-  hasSomeStackTrace = NimStackTrace or 
+  hasSomeStackTrace = NimStackTrace or
     defined(nativeStackTrace) and nativeStackTraceSupported
 
 when defined(nativeStacktrace) and nativeStackTraceSupported:
   type
-    TDl_info {.importc: "Dl_info", header: "<dlfcn.h>", 
+    TDl_info {.importc: "Dl_info", header: "<dlfcn.h>",
                final, pure.} = object
       dli_fname: cstring
       dli_fbase: pointer
@@ -98,7 +98,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
         tempDlInfo: TDl_info
     # This is allowed to be expensive since it only happens during crashes
     # (but this way you don't need manual stack tracing)
-    var size = backtrace(cast[ptr pointer](addr(tempAddresses)), 
+    var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
                          len(tempAddresses))
     var enabled = false
     for i in 0..size-1:
@@ -123,7 +123,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
 when not hasThreadSupport:
   var
     tempFrames: array [0..127, PFrame] # should not be alloc'd on stack
-  
+
 proc auxWriteStackTrace(f: PFrame, s: var string) =
   when hasThreadSupport:
     var
@@ -160,7 +160,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
     inc(i)
     b = b.prev
   for j in countdown(i-1, 0):
-    if tempFrames[j] == nil: 
+    if tempFrames[j] == nil:
       add(s, "(")
       add(s, $skipped)
       add(s, " calls omitted) ...")
@@ -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):
+  when defined(cpp):
+    if e[] of OutOfMemError:
+      showErrorMessage(e.name)
+      quitOrDebug()
+    else:
       pushCurrentException(e)
-      c_longjmp(excHandler.context, 1)
-  elif e[] of OutOfMemError:
-    showErrorMessage(e.name)
-    quitOrDebug()
+      {.emit: "throw NimException(`e`, `e`->name);".}
   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)
+    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:
-      # 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()
+      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
@@ -309,7 +317,7 @@ when not defined(noSignalHandler):
   proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
     template processSignal(s, action: expr) {.immediate,  dirty.} =
       if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
-      elif s == SIGSEGV: 
+      elif s == SIGSEGV:
         action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n")
       elif s == SIGABRT:
         when defined(endb):
diff --git a/tests/cpp/tcppraise.nim b/tests/cpp/tcppraise.nim
new file mode 100644
index 000000000..a9ea8e6ce
--- /dev/null
+++ b/tests/cpp/tcppraise.nim
@@ -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"
diff --git a/tests/exception/texceptionbreak.nim b/tests/exception/texceptionbreak.nim
index 76e986787..00dd8ed9f 100644
--- a/tests/exception/texceptionbreak.nim
+++ b/tests/exception/texceptionbreak.nim
@@ -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"
\ No newline at end of file
+echo "4"
diff --git a/tests/exception/texcsub.nim b/tests/exception/texcsub.nim
index 3dba357f9..02125d2c0 100644
--- a/tests/exception/texcsub.nim
+++ b/tests/exception/texcsub.nim
@@ -5,12 +5,12 @@ 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: 
+except:
   echo "wtf!?"
-  
+
 #OUT caught!
 
 
diff --git a/tests/exception/tfinally4.nim b/tests/exception/tfinally4.nim
index 05c57c4f5..3aa707ff6 100644
--- a/tests/exception/tfinally4.nim
+++ b/tests/exception/tfinally4.nim
@@ -8,19 +8,19 @@ discard """
 var raiseEx = true
 var returnA = true
 var returnB = false
- 
-proc main: int = 
+
+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"
diff --git a/tests/exception/tnestedreturn.nim b/tests/exception/tnestedreturn.nim
index 591638f0e..1480764f1 100644
--- a/tests/exception/tnestedreturn.nim
+++ b/tests/exception/tnestedreturn.nim
@@ -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
diff --git a/tests/exception/tonraise.nim b/tests/exception/tonraise.nim
index 1a555dd94..a155f0b8e 100644
--- a/tests/exception/tonraise.nim
+++ b/tests/exception/tonraise.nim
@@ -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,14 +17,14 @@ 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:
     echo("ESomething happened")
   except:
     echo("Some other error happened")
-    
+
   # test that raise handler is gone:
   try:
     genErrors("error!")
diff --git a/web/news.txt b/web/news.txt
index f792f5017..6cb92b581 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -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