arc: cursors for simple for loop variables (#15008)

* arc: cursors for simple for loop variables

* merged devel
This commit is contained in:
Andreas Rumpf
2020-07-17 15:24:36 +02:00
committed by GitHub
parent c2f80de1c7
commit d4984e069a
4 changed files with 52 additions and 7 deletions

View File

@@ -1062,5 +1062,5 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
if g.config.arcToExpand.hasKey(owner.name.s):
echo "--expandArc: ", owner.name.s
echo renderTree(result, {renderIr})
echo renderTree(result, {renderIr, renderNoComments})
echo "-- end of expandArc ------------------------"

View File

@@ -350,7 +350,7 @@ proc transformYield(c: PTransf, n: PNode): PNode =
# Choose the right assignment instruction according to the given ``lhs``
# node since it may not be a nkSym (a stack-allocated skForVar) but a
# nkDotExpr (a heap-allocated slot into the envP block)
case lhs.kind:
case lhs.kind
of nkSym:
internalAssert c.graph.config, lhs.sym.kind == skForVar
result = newAsgnStmt(c, nkFastAsgn, lhs, rhs)
@@ -592,6 +592,22 @@ proc findWrongOwners(c: PTransf, n: PNode) =
else:
for i in 0..<n.safeLen: findWrongOwners(c, n[i])
proc isSimpleIteratorVar(iter: PSym): bool =
proc rec(n: PNode; owner: PSym; dangerousYields: var int) =
case n.kind
of nkEmpty..nkNilLit: discard
of nkYieldStmt:
if n[0].kind == nkSym and n[0].sym.owner == owner:
discard "good: yield a single variable that we own"
else:
inc dangerousYields
else:
for c in n: rec(c, owner, dangerousYields)
var dangerousYields = 0
rec(iter.ast[bodyPos], iter, dangerousYields)
result = dangerousYields == 0
proc transformFor(c: PTransf, n: PNode): PNode =
# generate access statements for the parameters (unless they are constant)
# put mapping from formal parameters to actual parameters
@@ -624,18 +640,22 @@ proc transformFor(c: PTransf, n: PNode): PNode =
discard c.breakSyms.pop
let iter = call[0].sym
var v = newNodeI(nkVarSection, n.info)
for i in 0..<n.len - 2:
if n[i].kind == nkVarTuple:
for j in 0..<n[i].len-1:
addVar(v, copyTree(n[i][j])) # declare new vars
else:
if n[i].kind == nkSym and isSimpleIteratorVar(iter):
incl n[i].sym.flags, sfCursor
addVar(v, copyTree(n[i])) # declare new vars
stmtList.add(v)
# Bugfix: inlined locals belong to the invoking routine, not to the invoked
# iterator!
let iter = call[0].sym
var newC = newTransCon(getCurrOwner(c))
newC.forStmt = n
newC.forLoopBody = loopBody

View File

@@ -1,6 +1,6 @@
discard """
output: '''("string here", 80)'''
cmd: '''nim c --gc:arc --expandArc:main --hint:Performance:off $file'''
cmd: '''nim c --gc:arc --expandArc:main --expandArc:sio --hint:Performance:off $file'''
nimout: '''--expandArc: main
var
@@ -19,6 +19,24 @@ try:
:tmpD_2]
finally:
`=destroy`(:tmpD_2)
-- end of expandArc ------------------------
--expandArc: sio
block :tmp:
var x_cursor
var f = open("debug.txt", fmRead, 8000)
try:
var res
try:
res = TaintedString(newStringOfCap(80))
block :tmp_1:
while readLine(f, res):
x_cursor = res
echo [x_cursor]
finally:
`=destroy`(res)
finally:
close(f)
-- end of expandArc ------------------------'''
"""
@@ -33,3 +51,10 @@ proc main(cond: bool) =
echo x
main(false)
proc sio =
for x in lines("debug.txt"):
echo x
if false:
sio()

View File

@@ -28,13 +28,13 @@ var
try:
x = f()
block :tmp:
var i
var i_cursor
var i_1 = 0
block :tmp_1:
while i_1 < 4:
var :tmpD
i = i_1
if i == 2:
i_cursor = i_1
if i_cursor == 2:
return
add(a):
wasMoved(:tmpD)