newruntime: raising an exception works but currently leaks memory because currentException global is not an 'owned' ref
This commit is contained in:
parent
cb4e04d88e
commit
2846156e13
4 changed files with 60 additions and 6 deletions
|
|
@ -691,6 +691,8 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
[e, makeCString(typ.sym.name.s),
|
[e, makeCString(typ.sym.name.s),
|
||||||
makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.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))])
|
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:
|
else:
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,10 @@ proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
genOp(t.assignment, "=", ri)
|
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 =
|
proc genDestroy(c: Con; t: PType; dest: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
genOp(t.destructor, "=destroy", nil)
|
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)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
result = newTree(nkStmtList, snk, genWasMoved(ri, c))
|
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)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
|
|
@ -737,9 +741,17 @@ proc p(n: PNode; c: var Con): PNode =
|
||||||
result[1][0] = p(result[1][0], c)
|
result[1][0] = p(result[1][0], c)
|
||||||
of nkRaiseStmt:
|
of nkRaiseStmt:
|
||||||
if optNimV2 in c.graph.config.globalOptions:
|
if optNimV2 in c.graph.config.globalOptions:
|
||||||
# this is a bit hacky but we simply do not destroy exceptions that have
|
let t = n[0].typ
|
||||||
# been raised since the raise does consume the exception:
|
let tmp = getTemp(c, t, n.info)
|
||||||
result = copyTree(n)
|
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:
|
else:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
recurse(n, result)
|
recurse(n, result)
|
||||||
|
|
|
||||||
|
|
@ -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 genIf(c, x, callCodegenProc(c.graph, "nimDecWeakRef", c.info, x))
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedAsgn:
|
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 genIf(c, x, callCodegenProc(c.graph, "nimDecWeakRef", c.info, x))
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedDestructor:
|
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 genIf(c, xx, callCodegenProc(c.graph, "nimDecWeakRef", c.info, xx))
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedAsgn:
|
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 genIf(c, xx, callCodegenProc(c.graph, "nimDecWeakRef", c.info, xx))
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedDestructor:
|
of attachedDestructor:
|
||||||
|
|
|
||||||
38
tests/destructor/tv2_raise.nim
Normal file
38
tests/destructor/tv2_raise.nim
Normal file
|
|
@ -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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue