arc: cursors for simple for loop variables (#15008)
* arc: cursors for simple for loop variables * merged devel
This commit is contained in:
parent
c2f80de1c7
commit
d4984e069a
4 changed files with 52 additions and 7 deletions
|
|
@ -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 ------------------------"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue