summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-04-10 20:32:07 +0200
committerAraq <rumpf_a@web.de>2019-04-10 20:34:00 +0200
commit2846156e13b26ac566092e394e9900df52059039 (patch)
tree3df7699c9877e1bbf71431e5d30605ce8fe0a0be
parentcb4e04d88e1bd24f148e410512eb9f9a7948f078 (diff)
downloadNim-2846156e13b26ac566092e394e9900df52059039.tar.gz
newruntime: raising an exception works but currently leaks memory because currentException global is not an 'owned' ref
-rw-r--r--compiler/ccgstmts.nim2
-rw-r--r--compiler/injectdestructors.nim20
-rw-r--r--compiler/liftdestructors.nim6
-rw-r--r--tests/destructor/tv2_raise.nim38
4 files changed, 60 insertions, 6 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 49acad509..9dd70a703 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -691,6 +691,8 @@ proc genRaiseStmt(p: BProc, t: PNode) =
           [e, makeCString(typ.sym.name.s),
           makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.name.s),
           makeCString(toFileName(p.config, t.info)), rope(toLinenumber(t.info))])
+      if optNimV2 in p.config.globalOptions:
+        lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [e])
   else:
     genLineDir(p, t)
     # reraise the last exception:
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 6ec8193d1..45aae73a0 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -362,6 +362,10 @@ proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode =
   let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
   genOp(t.assignment, "=", ri)
 
+proc genCopyNoCheck(c: Con; t: PType; dest, ri: PNode): PNode =
+  let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
+  genOp(t.assignment, "=", ri)
+
 proc genDestroy(c: Con; t: PType; dest: PNode): PNode =
   let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
   genOp(t.destructor, "=destroy", nil)
@@ -608,7 +612,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
       var snk = genSink(c, dest.typ, dest, ri)
       snk.add ri
       result = newTree(nkStmtList, snk, genWasMoved(ri, c))
-    elif ri.sym.kind != skParam and isLastRead(ri, c):
+    elif ri.sym.kind != skParam and ri.sym.owner == c.owner and isLastRead(ri, c):
       # Rule 3: `=sink`(x, z); wasMoved(z)
       var snk = genSink(c, dest.typ, dest, ri)
       snk.add ri
@@ -737,9 +741,17 @@ proc p(n: PNode; c: var Con): PNode =
     result[1][0] = p(result[1][0], c)
   of nkRaiseStmt:
     if optNimV2 in c.graph.config.globalOptions:
-      # this is a bit hacky but we simply do not destroy exceptions that have
-      # been raised since the raise does consume the exception:
-      result = copyTree(n)
+      let t = n[0].typ
+      let tmp = getTemp(c, t, n.info)
+      var m = genCopyNoCheck(c, t, tmp, n[0])
+
+      m.add p(n[0], c)
+      result = newTree(nkStmtList, genWasMoved(tmp, c), m)
+      var toDisarm = n[0]
+      if toDisarm.kind == nkStmtListExpr: toDisarm = toDisarm.lastSon
+      if toDisarm.kind == nkSym and toDisarm.sym.owner == c.owner:
+        result.add genWasMoved(toDisarm, c)
+      result.add newTree(nkRaiseStmt, tmp)
     else:
       result = copyNode(n)
       recurse(n, result)
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index 2e239d42d..91882ac52 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -334,7 +334,7 @@ proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
     body.add genIf(c, x, callCodegenProc(c.graph, "nimDecWeakRef", c.info, x))
     body.add newAsgnStmt(x, y)
   of attachedAsgn:
-    body.add callCodegenProc(c.graph, "nimIncWeakRef", c.info, y)
+    body.add genIf(c, y, callCodegenProc(c.graph, "nimIncWeakRef", c.info, y))
     body.add genIf(c, x, callCodegenProc(c.graph, "nimDecWeakRef", c.info, x))
     body.add newAsgnStmt(x, y)
   of attachedDestructor:
@@ -382,7 +382,9 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
       body.add genIf(c, xx, callCodegenProc(c.graph, "nimDecWeakRef", c.info, xx))
       body.add newAsgnStmt(x, y)
     of attachedAsgn:
-      body.add callCodegenProc(c.graph, "nimIncWeakRef", c.info, y)
+      let yy = genBuiltin(c.graph, mAccessEnv, "accessEnv", y)
+      yy.typ = getSysType(c.graph, c.info, tyPointer)
+      body.add genIf(c, yy, callCodegenProc(c.graph, "nimIncWeakRef", c.info, yy))
       body.add genIf(c, xx, callCodegenProc(c.graph, "nimDecWeakRef", c.info, xx))
       body.add newAsgnStmt(x, y)
     of attachedDestructor:
diff --git a/tests/destructor/tv2_raise.nim b/tests/destructor/tv2_raise.nim
new file mode 100644
index 000000000..75ccadd49
--- /dev/null
+++ b/tests/destructor/tv2_raise.nim
@@ -0,0 +1,38 @@
+discard """
+  cmd: '''nim c --newruntime $file'''
+  output: '''OK 2
+4 1'''
+"""
+
+import strutils, math
+import system / ansi_c
+import core / allocators
+
+proc mainA =
+  var e: owned(ref ValueError)
+  new(e)
+  e.msg = "message"
+  raise e
+
+proc main =
+  raise newException(ValueError, "argh")
+
+var ok = 0
+try:
+  mainA()
+except ValueError:
+  inc ok
+except:
+  discard
+
+try:
+  main()
+except ValueError:
+  inc ok
+except:
+  discard
+
+echo "OK ", ok
+
+let (a, d) = allocCounters()
+discard cprintf("%ld %ld\n", a, d)