diff options
author | Araq <rumpf_a@web.de> | 2020-07-08 10:03:09 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-07-08 10:48:12 +0200 |
commit | ecf8cbbbe0be3cc722d59bdfbfffd3994f136c0e (patch) | |
tree | d04d9e0d7dfa571b4828d2e437a7e348cddda90d /compiler | |
parent | cdce245a235f3a8c255d0f782bc088546343b6ed (diff) | |
download | Nim-ecf8cbbbe0be3cc722d59bdfbfffd3994f136c0e.tar.gz |
fixes #14900
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/injectdestructors.nim | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 291cd36aa..67d61525e 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -41,6 +41,30 @@ type # means that 'x' escapes. We then destroy it # in the parent's scope (and also allocate it there). +type + Con = object + owner: PSym + g: ControlFlowGraph + jumpTargets: IntSet + destroys, topLevelVars: PNode + graph: ModuleGraph + emptyNode: PNode + otherRead: PNode + inLoop, inSpawn: int + uninit: IntSet # set of uninit'ed vars + uninitComputed: bool + + ProcessMode = enum + normal + consumed + sinkArg + +proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode = + let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info) + sym.typ = typ + s.vars.add(sym) + result = newSymNode(sym) + proc nestedScope(parent: var Scope): Scope = Scope(vars: @[], wasMoved: @[], final: @[], needsTry: false, parent: addr(parent)) @@ -99,7 +123,7 @@ type onlyCareAboutVars, producesValue -proc toTree(s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode = +proc toTree(c: var Con; s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode = if not s.needsTry: optimize(s) assert ret != nil if s.vars.len == 0 and s.final.len == 0 and s.wasMoved.len == 0: @@ -107,8 +131,11 @@ proc toTree(s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode = result = ret else: let isExpr = producesValue in flags and not isEmptyType(ret.typ) + var r = PNode(nil) if isExpr: result = newNodeIT(nkStmtListExpr, ret.info, ret.typ) + if ret.kind == nkStmtListExpr: + r = getTemp(c, s, ret.typ, ret.info) else: result = newNodeI(nkStmtList, ret.info) @@ -126,32 +153,15 @@ proc toTree(s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode = for m in s.wasMoved: finSection.add m for i in countdown(s.final.high, 0): finSection.add s.final[i] result.add newTryFinally(ret, finSection) - elif isExpr: - for m in s.wasMoved: result.add m - for i in countdown(s.final.high, 0): result.add s.final[i] - result.add ret else: - result.add ret + if r != nil: + result.add newTree(nkFastAsgn, r, ret) + else: + result.add ret for m in s.wasMoved: result.add m for i in countdown(s.final.high, 0): result.add s.final[i] - -type - Con = object - owner: PSym - g: ControlFlowGraph - jumpTargets: IntSet - destroys, topLevelVars: PNode - graph: ModuleGraph - emptyNode: PNode - otherRead: PNode - inLoop, inSpawn: int - uninit: IntSet # set of uninit'ed vars - uninitComputed: bool - - ProcessMode = enum - normal - consumed - sinkArg + if r != nil: + result.add r const toDebug {.strdefine.} = "" @@ -409,12 +419,6 @@ proc addTopVar(c: var Con; s: var Scope; v: PNode): ptr Scope = result = result.parent result[].vars.add v.sym -proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode = - let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info) - sym.typ = typ - s.vars.add(sym) - result = newSymNode(sym) - proc genDiscriminantAsgn(c: var Con; s: var Scope; n: PNode): PNode = # discriminator is ordinal value that doesn't need sink destroy # but fields within active case branch might need destruction @@ -661,7 +665,7 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = var ofScope = nestedScope(s) markEscapingVars(it[^1], ofScope) let ofResult = maybeVoid(it[^1], ofScope) - branch[^1] = toTree(ofScope, ofResult, treeFlags) + branch[^1] = toTree(c, ofScope, ofResult, treeFlags) result.add branch rememberParent(s, ofScope) @@ -671,7 +675,7 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = result.add p(n[0], c, s, normal) var bodyScope = nestedScope(s) let bodyResult = p(n[1], c, bodyScope, normal) - result.add toTree(bodyScope, bodyResult, treeFlags) + result.add toTree(c, bodyScope, bodyResult, treeFlags) rememberParent(s, bodyScope) dec c.inLoop @@ -682,7 +686,7 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = var bodyScope = nestedScope(s) markEscapingVars(n[1], bodyScope) let bodyResult = processCall(n[1], bodyScope) - result.add toTree(bodyScope, bodyResult, treeFlags) + result.add toTree(c, bodyScope, bodyResult, treeFlags) rememberParent(s, bodyScope) of nkIfStmt, nkIfExpr: @@ -695,12 +699,12 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = branchScope.parent = nil if it.kind in {nkElifBranch, nkElifExpr}: let cond = p(it[0], c, branchScope, normal) - branch[0] = toTree(branchScope, cond, {producesValue, onlyCareAboutVars}) + branch[0] = toTree(c, branchScope, cond, {producesValue, onlyCareAboutVars}) branchScope.parent = addr(s) markEscapingVars(it[^1], branchScope) var branchResult = processCall(it[^1], branchScope) - branch[^1] = toTree(branchScope, branchResult, treeFlags) + branch[^1] = toTree(c, branchScope, branchResult, treeFlags) result.add branch rememberParent(s, branchScope) @@ -710,7 +714,7 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = var tryScope = nestedScope(s) markEscapingVars(n[0], tryScope) var tryResult = maybeVoid(n[0], tryScope) - result.add toTree(tryScope, tryResult, treeFlags) + result.add toTree(c, tryScope, tryResult, treeFlags) rememberParent(s, tryScope) for i in 1..<n.len: @@ -719,7 +723,7 @@ template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = var branchScope = nestedScope(s) var branchResult = if it.kind == nkFinally: p(it[^1], c, branchScope, normal) else: processCall(it[^1], branchScope) - branch[^1] = toTree(branchScope, branchResult, treeFlags) + branch[^1] = toTree(c, branchScope, branchResult, treeFlags) result.add branch rememberParent(s, branchScope) @@ -1120,7 +1124,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = scope.final.add genDestroy(c, params[i]) #if optNimV2 in c.graph.config.globalOptions: # injectDefaultCalls(n, c) - result = toTree(scope, body, {}) + result = toTree(c, scope, body, {}) dbg: echo ">---------transformed-to--------->" echo renderTree(result, {renderIds}) |