destructors: progress

This commit is contained in:
Andreas Rumpf
2019-04-05 12:38:18 +02:00
parent 3e3a8bd4cd
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:
let it = n[i]
let L = it.len-1
let ri = it[L]
let L = it.len
let ri = it[L-1]
if it.kind == nkVarTuple and hasDestructor(ri.typ):
let x = lowerTupleUnpacking(c.graph, it, c.owner)
result.add p(x, c)
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]
doAssert v.kind == nkSym
# 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':
var varSection = copyNode(n)
var itCopy = copyNode(it)
for j in 0..L-1:
for j in 0..L-2:
itCopy.add it[j]
itCopy.add p(ri, c)
varSection.add itCopy
@@ -722,8 +722,9 @@ proc p(n: PNode; c: var Con): PNode =
recurse(n, result)
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
when false: # defined(nimDebugDestroys):
echo "injecting into ", n
when defined(nimDebugDestroys):
if owner.name.s == "main":
echo "injecting into ", n
if sfGeneratedOp in owner.flags: return n
var c: Con
c.owner = owner
@@ -758,7 +759,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
result.add body
when defined(nimDebugDestroys):
if true:
if owner.name.s == "main":
echo "------------------------------------"
echo owner.name.s, " transformed to: "
echo result

View File

@@ -266,7 +266,7 @@ proc newSeqCall(g: ModuleGraph; x, y: PNode): PNode =
proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
let lenCall = genBuiltin(g, mLengthStr, "len", y)
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
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)
var op = getSysMagic(c.graph, x.info, "setLen", mSetLengthSeq)
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) =
let i = declareCounter(c, body, firstOrd(c.graph.config, t))
@@ -606,6 +606,8 @@ template inst(field, t) =
if field.ast != nil:
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) =
## In the semantic pass this is called in strategic places
## 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.assignment = canon.assignment
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:
# we are very conservative here and assume the loop is never executed:
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])
setLen(tracked.init, oldState)
of nkObjConstr:

View File

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