destroyer pass: adaptations for the new destructor based runtime

This commit is contained in:
Andreas Rumpf 2018-07-27 18:21:32 +02:00
commit 700448f359
2 changed files with 27 additions and 7 deletions

View file

@ -258,8 +258,10 @@ proc registerDropBit(c: var Con; s: PSym) =
c.toDropBit[s.id] = result c.toDropBit[s.id] = result
# generate: # generate:
# if not sinkParam_AliveBit: `=destroy`(sinkParam) # if not sinkParam_AliveBit: `=destroy`(sinkParam)
c.destroys.add newTree(nkIfStmt, let t = s.typ.skipTypes({tyGenericInst, tyAlias, tySink})
newTree(nkElifBranch, newSymNode result, genDestroy(c, s.typ, newSymNode s))) if t.destructor != nil:
c.destroys.add newTree(nkIfStmt,
newTree(nkElifBranch, newSymNode result, genDestroy(c, t, newSymNode s)))
proc p(n: PNode; c: var Con): PNode proc p(n: PNode; c: var Con): PNode

View file

@ -197,13 +197,10 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case t.kind case t.kind
of tyNone, tyEmpty, tyVoid: discard of tyNone, tyEmpty, tyVoid: discard
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
tyPtr, tyString, tyRef, tyOpt: tyPtr, tyRef, tyOpt:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyArray, tySequence: of tyArray:
if {tfHasAsgn, tfUncheckedArray} * t.flags == {tfHasAsgn}: if {tfHasAsgn, tfUncheckedArray} * t.flags == {tfHasAsgn}:
if t.kind == tySequence:
# XXX add 'nil' handling here
body.add newSeqCall(c.c, x, y)
let i = declareCounter(c, body, firstOrd(c.c.config, t)) let i = declareCounter(c, body, firstOrd(c.c.config, t))
let whileLoop = genWhileLoop(c, i, x) let whileLoop = genWhileLoop(c, i, x)
let elemType = t.lastSon let elemType = t.lastSon
@ -213,6 +210,27 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
body.add whileLoop body.add whileLoop
else: else:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tySequence:
# note that tfHasAsgn is propagated so we need the check on
# 'selectedGC' here to determine if we have the new runtime.
if c.c.config.selectedGC == gcDestructors:
discard considerOverloadedOp(c, t, body, x, y)
elif tfHasAsgn in t.flags:
body.add newSeqCall(c.c, x, y)
let i = declareCounter(c, body, firstOrd(c.c.config, t))
let whileLoop = genWhileLoop(c, i, x)
let elemType = t.lastSon
liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType),
y.at(i, elemType))
addIncStmt(c, whileLoop.sons[1], i)
body.add whileLoop
else:
defaultOp(c, t, body, x, y)
of tyString:
if tfHasAsgn in t.flags:
discard considerOverloadedOp(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyObject, tyDistinct: of tyObject, tyDistinct:
if not considerOverloadedOp(c, t, body, x, y): if not considerOverloadedOp(c, t, body, x, y):
if t.sons[0] != nil: if t.sons[0] != nil: