diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index aaad53b64b..2017f7dffc 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -418,35 +418,6 @@ proc skipTrivialIndirections(n: PNode): PNode = result = result[1] else: break -proc getPotentialWrites(n: PNode; mutate: bool; result: var seq[PNode]) = - case n.kind: - of nkLiterals, nkIdent, nkFormalParams: discard - of nkSym: - if mutate: result.add n - of nkAsgn, nkFastAsgn, nkSinkAsgn: - getPotentialWrites(n[0], true, result) - getPotentialWrites(n[1], mutate, result) - of nkAddr, nkHiddenAddr: - getPotentialWrites(n[0], true, result) - of nkBracketExpr, nkDotExpr, nkCheckedFieldExpr: - getPotentialWrites(n[0], mutate, result) - of nkCallKinds: - case n.getMagic: - of mIncl, mExcl, mInc, mDec, mAppendStrCh, mAppendStrStr, mAppendSeqElem, - mAddr, mNew, mNewFinalize, mWasMoved, mDestroy: - getPotentialWrites(n[1], true, result) - for i in 2.. conf.target.floatSize * 3): result = true # requested anyway elif (tfFinal in pt.flags) and (pt[0] == nil): @@ -101,11 +98,7 @@ proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool = result = true # ordinary objects are always passed by reference, # otherwise casting doesn't work of tyTuple: - if s.typ.kind == tySink: - # it's a sink, so we pass it by value - result = false - else: - result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options) + result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options) else: result = false # first parameter and return type is 'lent T'? --> use pass by pointer diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 013ab1c506..be2df8c1f2 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -17,7 +17,7 @@ import ast, astalgo, msgs, renderer, magicsys, types, idents, options, lowerings, modulegraphs, lineinfos, parampatterns, sighashes, liftdestructors, optimizer, - varpartitions, aliasanalysis, dfa, wordrecg + varpartitions, aliasanalysis, dfa, wordrecg, trees import std/[strtabs, tables, strutils, intsets] @@ -1244,6 +1244,55 @@ when false: for i in 0.. 0: + result.add replaceSinkParam(n, mapping) + else: + result = n + proc injectDestructorCalls*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n: PNode): PNode = when toDebug.len > 0: shouldDebug = toDebug == owner.name.s or toDebug == "always" @@ -1257,15 +1306,24 @@ proc injectDestructorCalls*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n: var scope = Scope(body: n) let body = p(n, c, scope, normal) + var sinkParams = newSeq[PSym]() + if owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter}: let params = owner.typ.n for i in 1.. 0: + result = addSinkCopy(c, scope, sinkParams, result) + dbg: echo ">---------transformed-to--------->" echo renderTree(result, {renderIds}) diff --git a/compiler/trees.nim b/compiler/trees.nim index da58878f82..6d85f920c8 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -243,3 +243,32 @@ proc isRunnableExamples*(n: PNode): bool = proc skipAddr*(n: PNode): PNode {.inline.} = result = if n.kind in {nkAddr, nkHiddenAddr}: n[0] else: n + +proc getPotentialWrites*(n: PNode; mutate: bool; result: var seq[PNode]) = + case n.kind: + of nkLiterals, nkIdent, nkFormalParams: discard + of nkSym: + if mutate: result.add n + of nkAsgn, nkFastAsgn, nkSinkAsgn: + getPotentialWrites(n[0], true, result) + getPotentialWrites(n[1], mutate, result) + of nkAddr, nkHiddenAddr: + getPotentialWrites(n[0], true, result) + of nkBracketExpr, nkDotExpr, nkCheckedFieldExpr: + getPotentialWrites(n[0], mutate, result) + of nkCallKinds: + case n.getMagic: + of mIncl, mExcl, mInc, mDec, mAppendStrCh, mAppendStrStr, mAppendSeqElem, + mAddr, mNew, mNewFinalize, mWasMoved, mDestroy: + getPotentialWrites(n[1], true, result) + for i in 2..