VM: don't inject destructor calls, refs #7041
This commit is contained in:
parent
66a76d3165
commit
24902394f7
4 changed files with 29 additions and 23 deletions
|
|
@ -24,7 +24,8 @@ import
|
||||||
sempass2, lowerings, destroyer, liftlocals,
|
sempass2, lowerings, destroyer, liftlocals,
|
||||||
modulegraphs, lineinfos
|
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
|
import closureiters, lambdalifting
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ type
|
||||||
inlining: int # > 0 if we are in inlining context (copy vars)
|
inlining: int # > 0 if we are in inlining context (copy vars)
|
||||||
nestedProcs: int # > 0 if we are in a nested proc
|
nestedProcs: int # > 0 if we are in a nested proc
|
||||||
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
|
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
|
||||||
deferDetected, tooEarly, needsDestroyPass: bool
|
deferDetected, tooEarly, needsDestroyPass, noDestructors: bool
|
||||||
graph: ModuleGraph
|
graph: ModuleGraph
|
||||||
PTransf = ref TTransfContext
|
PTransf = ref TTransfContext
|
||||||
|
|
||||||
|
|
@ -130,7 +131,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
if s.typ != nil and s.typ.callConv == ccClosure:
|
if s.typ != nil and s.typ.callConv == ccClosure:
|
||||||
if s.kind in routineKinds:
|
if s.kind in routineKinds:
|
||||||
discard transformBody(c.graph, s)
|
discard transformBody(c.graph, s, true, c.noDestructors)
|
||||||
if s.kind == skIterator:
|
if s.kind == skIterator:
|
||||||
if c.tooEarly: return n
|
if c.tooEarly: return n
|
||||||
else: return liftIterSym(c.graph, n, getCurrOwner(c))
|
else: return liftIterSym(c.graph, n, getCurrOwner(c))
|
||||||
|
|
@ -611,7 +612,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode))
|
add(stmtList, newAsgnStmt(c, nkFastAsgn, temp, arg.PTransNode))
|
||||||
idNodeTablePut(newC.mapping, formal, temp)
|
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)
|
pushInfoContext(c.graph.config, n.info)
|
||||||
inc(c.inlining)
|
inc(c.inlining)
|
||||||
add(stmtList, transform(c, body))
|
add(stmtList, transform(c, body))
|
||||||
|
|
@ -1029,7 +1030,8 @@ template liftDefer(c, root) =
|
||||||
if c.deferDetected:
|
if c.deferDetected:
|
||||||
liftDeferAux(root)
|
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
|
assert prc.kind in routineKinds
|
||||||
|
|
||||||
if prc.transformedBody != nil:
|
if prc.transformedBody != nil:
|
||||||
|
|
@ -1037,14 +1039,14 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache = true): PNode =
|
||||||
elif nfTransf in prc.ast[bodyPos].flags or prc.kind in {skTemplate}:
|
elif nfTransf in prc.ast[bodyPos].flags or prc.kind in {skTemplate}:
|
||||||
result = prc.ast[bodyPos]
|
result = prc.ast[bodyPos]
|
||||||
else:
|
else:
|
||||||
|
|
||||||
prc.transformedBody = newNode(nkEmpty) # protects from recursion
|
prc.transformedBody = newNode(nkEmpty) # protects from recursion
|
||||||
var c = openTransf(g, prc.getModule, "")
|
var c = openTransf(g, prc.getModule, "")
|
||||||
|
c.noDestructors = noDestructors
|
||||||
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly)
|
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly)
|
||||||
result = processTransf(c, result, prc)
|
result = processTransf(c, result, prc)
|
||||||
liftDefer(c, result)
|
liftDefer(c, result)
|
||||||
result = liftLocalsIfRequested(prc, result, g.cache, g.config)
|
result = liftLocalsIfRequested(prc, result, g.cache, g.config)
|
||||||
if c.needsDestroyPass: #and newDestructors:
|
if c.needsDestroyPass and not noDestructors:
|
||||||
result = injectDestructorCalls(g, prc, result)
|
result = injectDestructorCalls(g, prc, result)
|
||||||
|
|
||||||
if prc.isIterator:
|
if prc.isIterator:
|
||||||
|
|
@ -1072,7 +1074,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||||
result = injectDestructorCalls(g, module, result)
|
result = injectDestructorCalls(g, module, result)
|
||||||
incl(result.flags, nfTransf)
|
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:
|
if nfTransf in n.flags:
|
||||||
result = n
|
result = n
|
||||||
else:
|
else:
|
||||||
|
|
@ -1081,6 +1084,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||||
liftDefer(c, result)
|
liftDefer(c, result)
|
||||||
# expressions are not to be injected with destructor calls as that
|
# expressions are not to be injected with destructor calls as that
|
||||||
# the list of top level statements needs to be collected before.
|
# 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)
|
result = injectDestructorCalls(g, module, result)
|
||||||
incl(result.flags, nfTransf)
|
incl(result.flags, nfTransf)
|
||||||
|
|
|
||||||
|
|
@ -1822,7 +1822,7 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
|
||||||
"NimScript: attempt to call non-routine: " & sym.name.s)
|
"NimScript: attempt to call non-routine: " & sym.name.s)
|
||||||
|
|
||||||
proc evalStmt*(c: PCtx, n: PNode) =
|
proc evalStmt*(c: PCtx, n: PNode) =
|
||||||
let n = transformExpr(c.graph, c.module, n)
|
let n = transformExpr(c.graph, c.module, n, noDestructors = true)
|
||||||
let start = genStmt(c, n)
|
let start = genStmt(c, n)
|
||||||
# execute new instructions; this redundant opcEof check saves us lots
|
# execute new instructions; this redundant opcEof check saves us lots
|
||||||
# of allocations in 'execute':
|
# of allocations in 'execute':
|
||||||
|
|
@ -1830,7 +1830,7 @@ proc evalStmt*(c: PCtx, n: PNode) =
|
||||||
discard execute(c, start)
|
discard execute(c, start)
|
||||||
|
|
||||||
proc evalExpr*(c: PCtx, n: PNode): PNode =
|
proc evalExpr*(c: PCtx, n: PNode): PNode =
|
||||||
let n = transformExpr(c.graph, c.module, n)
|
let n = transformExpr(c.graph, c.module, n, noDestructors = true)
|
||||||
let start = genExpr(c, n)
|
let start = genExpr(c, n)
|
||||||
assert c.code[start].opcode != opcEof
|
assert c.code[start].opcode != opcEof
|
||||||
result = execute(c, start)
|
result = execute(c, start)
|
||||||
|
|
@ -1877,7 +1877,7 @@ const evalPass* = makePass(myOpen, myProcess, myClose)
|
||||||
proc evalConstExprAux(module: PSym;
|
proc evalConstExprAux(module: PSym;
|
||||||
g: ModuleGraph; prc: PSym, n: PNode,
|
g: ModuleGraph; prc: PSym, n: PNode,
|
||||||
mode: TEvalMode): PNode =
|
mode: TEvalMode): PNode =
|
||||||
let n = transformExpr(g, module, n)
|
let n = transformExpr(g, module, n, noDestructors = true)
|
||||||
setupGlobalCtx(module, g)
|
setupGlobalCtx(module, g)
|
||||||
var c = PCtx g.vm
|
var c = PCtx g.vm
|
||||||
let oldMode = c.mode
|
let oldMode = c.mode
|
||||||
|
|
|
||||||
|
|
@ -2153,7 +2153,8 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
s.ast.sons[miscPos] = x
|
s.ast.sons[miscPos] = x
|
||||||
# thanks to the jmp we can add top level statements easily and also nest
|
# thanks to the jmp we can add top level statements easily and also nest
|
||||||
# procs easily:
|
# procs easily:
|
||||||
let body = transformBody(c.graph, s, cache = not isCompileTimeProc(s))
|
let body = transformBody(c.graph, s, cache = not isCompileTimeProc(s),
|
||||||
|
noDestructors = true)
|
||||||
let procStart = c.xjmp(body, opcJmp, 0)
|
let procStart = c.xjmp(body, opcJmp, 0)
|
||||||
var p = PProc(blocks: @[], sym: s)
|
var p = PProc(blocks: @[], sym: s)
|
||||||
let oldPrc = c.prc
|
let oldPrc = c.prc
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,11 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
import typetraits
|
# import typetraits
|
||||||
# strs already imported allocators for us.
|
# strs already imported allocators for us.
|
||||||
|
|
||||||
|
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
|
||||||
|
|
||||||
## Default seq implementation used by Nim's core.
|
## Default seq implementation used by Nim's core.
|
||||||
type
|
type
|
||||||
NimSeqPayload {.core.}[T] = object
|
NimSeqPayload {.core.}[T] = object
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue