diff options
author | Araq <rumpf_a@web.de> | 2019-04-10 20:32:07 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-04-10 20:34:00 +0200 |
commit | 2846156e13b26ac566092e394e9900df52059039 (patch) | |
tree | 3df7699c9877e1bbf71431e5d30605ce8fe0a0be | |
parent | cb4e04d88e1bd24f148e410512eb9f9a7948f078 (diff) | |
download | Nim-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.nim | 2 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 20 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 6 | ||||
-rw-r--r-- | tests/destructor/tv2_raise.nim | 38 |
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) |