destructors: progress
This commit is contained in:
parent
3e3a8bd4cd
commit
efeee326f8
4 changed files with 29 additions and 12 deletions
|
|
@ -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,8 +722,9 @@ 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):
|
||||||
echo "injecting into ", n
|
if owner.name.s == "main":
|
||||||
|
echo "injecting into ", n
|
||||||
if sfGeneratedOp in owner.flags: return n
|
if sfGeneratedOp in owner.flags: return n
|
||||||
var c: Con
|
var c: Con
|
||||||
c.owner = owner
|
c.owner = owner
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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, " ")]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue