destructors: progress

This commit is contained in:
Andreas Rumpf 2019-04-05 12:38:18 +02:00
commit efeee326f8
4 changed files with 29 additions and 12 deletions

View file

@ -660,13 +660,13 @@ proc p(n: PNode; c: var Con): PNode =
for i in 0..<n.len: for i in 0..<n.len:
let it = n[i] let it = n[i]
let L = it.len-1 let L = it.len
let ri = it[L] let ri = it[L-1]
if it.kind == nkVarTuple and hasDestructor(ri.typ): if it.kind == nkVarTuple and hasDestructor(ri.typ):
let x = lowerTupleUnpacking(c.graph, it, c.owner) let x = lowerTupleUnpacking(c.graph, it, c.owner)
result.add p(x, c) result.add p(x, c)
elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isCursor(it[0]): elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isCursor(it[0]):
for j in 0..L-2: for j in 0..L-3:
let v = it[j] let v = it[j]
doAssert v.kind == nkSym doAssert v.kind == nkSym
# move the variable declaration to the top of the frame: # move the variable declaration to the top of the frame:
@ -681,7 +681,7 @@ proc p(n: PNode; c: var Con): PNode =
# keep it, but transform 'ri': # keep it, but transform 'ri':
var varSection = copyNode(n) var varSection = copyNode(n)
var itCopy = copyNode(it) var itCopy = copyNode(it)
for j in 0..L-1: for j in 0..L-2:
itCopy.add it[j] itCopy.add it[j]
itCopy.add p(ri, c) itCopy.add p(ri, c)
varSection.add itCopy varSection.add itCopy
@ -722,7 +722,8 @@ proc p(n: PNode; c: var Con): PNode =
recurse(n, result) recurse(n, result)
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
when false: # defined(nimDebugDestroys): when defined(nimDebugDestroys):
if owner.name.s == "main":
echo "injecting into ", n echo "injecting into ", n
if sfGeneratedOp in owner.flags: return n if sfGeneratedOp in owner.flags: return n
var c: Con var c: Con
@ -758,7 +759,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
result.add body result.add body
when defined(nimDebugDestroys): when defined(nimDebugDestroys):
if true: if owner.name.s == "main":
echo "------------------------------------" echo "------------------------------------"
echo owner.name.s, " transformed to: " echo owner.name.s, " transformed to: "
echo result echo result

View file

@ -266,7 +266,7 @@ proc newSeqCall(g: ModuleGraph; x, y: PNode): PNode =
proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode = proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
let lenCall = genBuiltin(g, mLengthStr, "len", y) let lenCall = genBuiltin(g, mLengthStr, "len", y)
lenCall.typ = getSysType(g, x.info, tyInt) lenCall.typ = getSysType(g, x.info, tyInt)
result = genBuiltin(g, mSetLengthStr, "setLen", genAddr(g, x)) result = genBuiltin(g, mSetLengthStr, "setLen", x) # genAddr(g, x))
result.add lenCall result.add lenCall
proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode = proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
@ -274,7 +274,7 @@ proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
lenCall.typ = getSysType(c.graph, x.info, tyInt) lenCall.typ = getSysType(c.graph, x.info, tyInt)
var op = getSysMagic(c.graph, x.info, "setLen", mSetLengthSeq) var op = getSysMagic(c.graph, x.info, "setLen", mSetLengthSeq)
op = c.c.instTypeBoundOp(c.c, op, t, c.info, attachedAsgn, 1) op = c.c.instTypeBoundOp(c.c, op, t, c.info, attachedAsgn, 1)
result = newTree(nkCall, newSymNode(op, x.info), genAddr(c.graph, x), lenCall) result = newTree(nkCall, newSymNode(op, x.info), x, lenCall)
proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let i = declareCounter(c, body, firstOrd(c.graph.config, t)) let i = declareCounter(c, body, firstOrd(c.graph.config, t))
@ -606,6 +606,8 @@ template inst(field, t) =
if field.ast != nil: if field.ast != nil:
patchBody(c, field.ast, info) patchBody(c, field.ast, info)
proc isTrival(s: PSym): bool {.inline.} = s == nil or s.ast[bodyPos].len == 0
proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) = proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
## In the semantic pass this is called in strategic places ## In the semantic pass this is called in strategic places
## to ensure we lift assignment, destructors and moves properly. ## to ensure we lift assignment, destructors and moves properly.
@ -647,3 +649,8 @@ proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
orig.destructor = canon.destructor orig.destructor = canon.destructor
orig.assignment = canon.assignment orig.assignment = canon.assignment
orig.sink = canon.sink orig.sink = canon.sink
#if not isTrival(orig.destructor):
#or not isTrival(orig.assignment) or
# not isTrival(orig.sink):
# orig.flags.incl tfHasAsgn

View file

@ -821,7 +821,16 @@ proc track(tracked: PEffects, n: PNode) =
of nkForStmt, nkParForStmt: of nkForStmt, nkParForStmt:
# we are very conservative here and assume the loop is never executed: # we are very conservative here and assume the loop is never executed:
let oldState = tracked.init.len let oldState = tracked.init.len
for i in 0 ..< len(n): for i in 0 .. len(n)-3:
let it = n[i]
track(tracked, it)
if tracked.owner.kind != skMacro:
if it.kind == nkVarTuple:
for x in it:
createTypeBoundOps(tracked.c, x.typ, x.info)
else:
createTypeBoundOps(tracked.c, it.typ, it.info)
for i in len(n)-2..len(n)-1:
track(tracked, n.sons[i]) track(tracked, n.sons[i])
setLen(tracked.init, oldState) setLen(tracked.init, oldState)
of nkObjConstr: of nkObjConstr:

View file

@ -3,7 +3,7 @@ discard """
output: '''hi output: '''hi
ho ho
ha ha
1 1''' 7 1'''
""" """
import allocators import allocators
@ -75,7 +75,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
break break
i = j i = j
when false: when true:
let input = "$test{} $this is ${an{ example}} " let input = "$test{} $this is ${an{ example}} "
let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"), let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"),
(ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")] (ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")]