VM: don't inject destructor calls, refs #7041

This commit is contained in:
Andreas Rumpf 2018-11-06 19:36:29 +01:00
commit 24902394f7
4 changed files with 29 additions and 23 deletions

View file

@ -24,7 +24,8 @@ import
sempass2, lowerings, destroyer, liftlocals,
modulegraphs, lineinfos
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
noDestructors = false): PNode
import closureiters, lambdalifting
@ -48,7 +49,7 @@ type
inlining: int # > 0 if we are in inlining context (copy vars)
nestedProcs: int # > 0 if we are in a nested proc
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
deferDetected, tooEarly, needsDestroyPass: bool
deferDetected, tooEarly, needsDestroyPass, noDestructors: bool
graph: ModuleGraph
PTransf = ref TTransfContext
@ -130,7 +131,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
let s = n.sym
if s.typ != nil and s.typ.callConv == ccClosure:
if s.kind in routineKinds:
discard transformBody(c.graph, s)
discard transformBody(c.graph, s, true, c.noDestructors)
if s.kind == skIterator:
if c.tooEarly: return n
else: return liftIterSym(c.graph, n, getCurrOwner(c))
@ -159,7 +160,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
return
tc = tc.next
result = b
proc transformSym(c: PTransf, n: PNode): PTransNode =
result = PTransNode(transformSymAux(c, n))
@ -243,7 +244,7 @@ proc newLabel(c: PTransf, n: PNode): PSym =
result.name = getIdent(c.graph.cache, genPrefix & $result.id)
proc transformBlock(c: PTransf, n: PNode): PTransNode =
var labl: PSym
var labl: PSym
if c.inlining > 0:
labl = newLabel(c, n[0])
idNodeTablePut(c.transCon.mapping, n[0].sym, newSymNode(labl))
@ -611,7 +612,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode))
idNodeTablePut(newC.mapping, formal, temp)
let body = transformBody(c.graph, iter)
let body = transformBody(c.graph, iter, true, c.noDestructors)
pushInfoContext(c.graph.config, n.info)
inc(c.inlining)
add(stmtList, transform(c, body))
@ -1029,7 +1030,8 @@ template liftDefer(c, root) =
if c.deferDetected:
liftDeferAux(root)
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode =
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
noDestructors = false): PNode =
assert prc.kind in routineKinds
if prc.transformedBody != nil:
@ -1037,22 +1039,22 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode =
elif nfTransf in prc.ast[bodyPos].flags or prc.kind in {skTemplate}:
result = prc.ast[bodyPos]
else:
prc.transformedBody = newNode(nkEmpty) # protects from recursion
var c = openTransf(g, prc.getModule, "")
c.noDestructors = noDestructors
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly)
result = processTransf(c, result, prc)
liftDefer(c, result)
result = liftLocalsIfRequested(prc, result, g.cache, g.config)
if c.needsDestroyPass: #and newDestructors:
if c.needsDestroyPass and not noDestructors:
result = injectDestructorCalls(g, prc, result)
if prc.isIterator:
result = g.transformClosureIterator(prc, result)
incl(result.flags, nfTransf)
let cache = cache or prc.typ.callConv == ccInline
let cache = cache or prc.typ.callConv == ccInline
if cache:
# genProc for inline procs will be called multiple times from diffrent modules,
# it is important to transform exactly once to get sym ids and locations right
@ -1072,7 +1074,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
result = injectDestructorCalls(g, module, result)
incl(result.flags, nfTransf)
proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode;
noDestructors = false): PNode =
if nfTransf in n.flags:
result = n
else:
@ -1081,6 +1084,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
liftDefer(c, result)
# expressions are not to be injected with destructor calls as that
# the list of top level statements needs to be collected before.
if c.needsDestroyPass:
if c.needsDestroyPass and not noDestructors:
result = injectDestructorCalls(g, module, result)
incl(result.flags, nfTransf)