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
commit d4984e069a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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): if g.config.arcToExpand.hasKey(owner.name.s):
echo "--expandArc: ", owner.name.s echo "--expandArc: ", owner.name.s
echo renderTree(result, {renderIr}) echo renderTree(result, {renderIr, renderNoComments})
echo "-- end of expandArc ------------------------" 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`` # Choose the right assignment instruction according to the given ``lhs``
# node since it may not be a nkSym (a stack-allocated skForVar) but a # node since it may not be a nkSym (a stack-allocated skForVar) but a
# nkDotExpr (a heap-allocated slot into the envP block) # nkDotExpr (a heap-allocated slot into the envP block)
case lhs.kind: case lhs.kind
of nkSym: of nkSym:
internalAssert c.graph.config, lhs.sym.kind == skForVar internalAssert c.graph.config, lhs.sym.kind == skForVar
result = newAsgnStmt(c, nkFastAsgn, lhs, rhs) result = newAsgnStmt(c, nkFastAsgn, lhs, rhs)
@ -592,6 +592,22 @@ proc findWrongOwners(c: PTransf, n: PNode) =
else: else:
for i in 0..<n.safeLen: findWrongOwners(c, n[i]) 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 = proc transformFor(c: PTransf, n: PNode): PNode =
# generate access statements for the parameters (unless they are constant) # generate access statements for the parameters (unless they are constant)
# put mapping from formal parameters to actual parameters # put mapping from formal parameters to actual parameters
@ -624,18 +640,22 @@ proc transformFor(c: PTransf, n: PNode): PNode =
discard c.breakSyms.pop discard c.breakSyms.pop
let iter = call[0].sym
var v = newNodeI(nkVarSection, n.info) var v = newNodeI(nkVarSection, n.info)
for i in 0..<n.len - 2: for i in 0..<n.len - 2:
if n[i].kind == nkVarTuple: if n[i].kind == nkVarTuple:
for j in 0..<n[i].len-1: for j in 0..<n[i].len-1:
addVar(v, copyTree(n[i][j])) # declare new vars addVar(v, copyTree(n[i][j])) # declare new vars
else: else:
if n[i].kind == nkSym and isSimpleIteratorVar(iter):
incl n[i].sym.flags, sfCursor
addVar(v, copyTree(n[i])) # declare new vars addVar(v, copyTree(n[i])) # declare new vars
stmtList.add(v) stmtList.add(v)
# Bugfix: inlined locals belong to the invoking routine, not to the invoked # Bugfix: inlined locals belong to the invoking routine, not to the invoked
# iterator! # iterator!
let iter = call[0].sym
var newC = newTransCon(getCurrOwner(c)) var newC = newTransCon(getCurrOwner(c))
newC.forStmt = n newC.forStmt = n
newC.forLoopBody = loopBody newC.forLoopBody = loopBody

View file

@ -1,6 +1,6 @@
discard """ discard """
output: '''("string here", 80)''' 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 nimout: '''--expandArc: main
var var
@ -19,6 +19,24 @@ try:
:tmpD_2] :tmpD_2]
finally: finally:
`=destroy`(:tmpD_2) `=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 ------------------------''' -- end of expandArc ------------------------'''
""" """
@ -33,3 +51,10 @@ proc main(cond: bool) =
echo x echo x
main(false) main(false)
proc sio =
for x in lines("debug.txt"):
echo x
if false:
sio()

View file

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