diff options
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/transf.nim | 24 | ||||
-rw-r--r-- | tests/arc/topt_cursor.nim | 27 | ||||
-rw-r--r-- | tests/arc/topt_wasmoved_destroy_pairs.nim | 6 |
4 files changed, 52 insertions, 7 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 99eefca57..752438180 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -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 ------------------------" diff --git a/compiler/transf.nim b/compiler/transf.nim index be559abb8..7aa18bf52 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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 diff --git a/tests/arc/topt_cursor.nim b/tests/arc/topt_cursor.nim index 63f261877..a8020e72b 100644 --- a/tests/arc/topt_cursor.nim +++ b/tests/arc/topt_cursor.nim @@ -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() diff --git a/tests/arc/topt_wasmoved_destroy_pairs.nim b/tests/arc/topt_wasmoved_destroy_pairs.nim index 4d248492b..2a6391dd2 100644 --- a/tests/arc/topt_wasmoved_destroy_pairs.nim +++ b/tests/arc/topt_wasmoved_destroy_pairs.nim @@ -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) |