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