diff options
author | Araq <rumpf_a@web.de> | 2020-07-07 23:10:00 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-07-08 10:48:12 +0200 |
commit | b17e1efc67a64ce6acd2ddf4f432879f3bf739e2 (patch) | |
tree | 88cf6681680f471880671aa342925081541f8576 /compiler | |
parent | 87f6a9592cbbace5e8f0d647841b4490bb7c0f1f (diff) | |
download | Nim-b17e1efc67a64ce6acd2ddf4f432879f3bf739e2.tar.gz |
progress
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/injectdestructors.nim | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index bf0206055..e57898ae8 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -91,17 +91,23 @@ proc optimize(s: var Scope) = filterNil(wasMoved) filterNil(final) -proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): PNode = +type + ToTreeFlag = enum + onlyCareAboutVars, + producesValue + +proc toTree(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: # trivial, nothing was done: result = ret else: - if isEmptyType(ret.typ): - result = newNodeI(nkStmtList, ret.info) - else: + let isExpr = producesValue in flags and not isEmptyType(ret.typ) + if isExpr: result = newNodeIT(nkStmtListExpr, ret.info, ret.typ) + else: + result = newNodeI(nkStmtList, ret.info) if s.vars.len > 0: let varSection = newNodeI(nkVarSection, ret.info) @@ -109,7 +115,7 @@ proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): PNode = varSection.add newTree(nkIdentDefs, newSymNode(tmp), newNodeI(nkEmpty, ret.info), newNodeI(nkEmpty, ret.info)) result.add varSection - if onlyCareAboutVars: + if onlyCareAboutVars in flags: result.add ret s.vars.setLen 0 elif s.needsTry: @@ -117,8 +123,11 @@ proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): 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: - #assert isEmptyType(ret.typ) result.add ret for m in s.wasMoved: result.add m for i in countdown(s.final.high, 0): result.add s.final[i] @@ -593,22 +602,25 @@ proc pVarTopLevel(v: PNode; c: var Con; s: var Scope; ri, res: PNode) = elif ri.kind != nkEmpty: res.add moveOrCopy(v, ri, c, s, isDecl = true) -template handleNestedTempl(n: untyped, processCall: untyped) = +template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) = template maybeVoid(child, s): untyped = if isEmptyType(child.typ): p(child, c, s, normal) else: processCall(child, s) + let treeFlags = if not isEmptyType(n.typ) and not alwaysStmt: {producesValue} else: {} case n.kind of nkStmtList, nkStmtListExpr: # a statement list does not open a new scope if n.len == 0: return n result = copyNode(n) + if alwaysStmt: result.typ = nil for i in 0..<n.len-1: result.add p(n[i], c, s, normal) result.add maybeVoid(n[^1], s) of nkCaseStmt: result = copyNode(n) + if alwaysStmt: result.typ = nil result.add p(n[0], c, s, normal) for i in 1..<n.len: let it = n[i] @@ -619,7 +631,7 @@ template handleNestedTempl(n: untyped, processCall: untyped) = branch[j] = copyTree(it[j]) var ofScope = nestedScope(s) let ofResult = maybeVoid(it[^1], ofScope) - branch[^1] = toTree(ofScope, ofResult) + branch[^1] = toTree(ofScope, ofResult, treeFlags) result.add branch rememberParent(s, ofScope) @@ -629,20 +641,22 @@ template handleNestedTempl(n: untyped, processCall: untyped) = 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) + result.add toTree(bodyScope, bodyResult, treeFlags) rememberParent(s, bodyScope) dec c.inLoop of nkBlockStmt, nkBlockExpr: result = copyNode(n) + if alwaysStmt: result.typ = nil result.add n[0] var bodyScope = nestedScope(s) let bodyResult = processCall(n[1], bodyScope) - result.add toTree(bodyScope, bodyResult) + result.add toTree(bodyScope, bodyResult, treeFlags) rememberParent(s, bodyScope) of nkIfStmt, nkIfExpr: result = copyNode(n) + if alwaysStmt: result.typ = nil for i in 0..<n.len: let it = n[i] var branch = shallowCopy(it) @@ -650,19 +664,20 @@ template handleNestedTempl(n: untyped, processCall: untyped) = branchScope.parent = nil if it.kind in {nkElifBranch, nkElifExpr}: let cond = p(it[0], c, branchScope, normal) - branch[0] = toTree(branchScope, cond, onlyCareAboutVars = true) + branch[0] = toTree(branchScope, cond, {producesValue, onlyCareAboutVars}) branchScope.parent = addr(s) var branchResult = processCall(it[^1], branchScope) - branch[^1] = toTree(branchScope, branchResult) + branch[^1] = toTree(branchScope, branchResult, treeFlags) result.add branch rememberParent(s, branchScope) of nkTryStmt: result = copyNode(n) + if alwaysStmt: result.typ = nil var tryScope = nestedScope(s) var tryResult = maybeVoid(n[0], tryScope) - result.add toTree(tryScope, tryResult) + result.add toTree(tryScope, tryResult, treeFlags) rememberParent(s, tryScope) for i in 1..<n.len: @@ -671,12 +686,13 @@ template handleNestedTempl(n: untyped, processCall: untyped) = 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) + branch[^1] = toTree(branchScope, branchResult, treeFlags) result.add branch rememberParent(s, branchScope) of nkWhen: # This should be a "when nimvm" node. result = copyTree(n) + if alwaysStmt: result.typ = nil result[1][0] = processCall(n[1][0], s) else: assert(false) @@ -708,7 +724,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode = if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt, nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt, nkTryStmt}: template process(child, s): untyped = p(child, c, s, mode) - handleNestedTempl(n, process) + handleNestedTempl(n, process, false) elif mode == sinkArg: if n.containsConstSeq: # const sequences are not mutable and so we need to pass a copy to the @@ -994,7 +1010,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod result = genSink(c, s, dest, p(ri, c, s, sinkArg), isDecl) of nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt: template process(child, s): untyped = moveOrCopy(dest, child, c, s, isDecl) - handleNestedTempl(ri, process) + handleNestedTempl(ri, process, true) of nkRaiseStmt: result = pRaiseStmt(ri, c, s) else: @@ -1071,7 +1087,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(scope, body, {}) dbg: echo ">---------transformed-to--------->" echo renderTree(result, {renderIds}) |