injectdestructors: refactoring, added more cases explicitly (#14929)
This commit is contained in:
parent
95808c2806
commit
a61a7889b8
1 changed files with 68 additions and 7 deletions
|
|
@ -706,7 +706,7 @@ proc pRaiseStmt(n: PNode, c: var Con; s: var Scope): PNode =
|
||||||
|
|
||||||
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
|
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
|
||||||
nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt}:
|
nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt, nkTryStmt}:
|
||||||
template process(child, s): untyped = p(child, c, s, mode)
|
template process(child, s): untyped = p(child, c, s, mode)
|
||||||
handleNestedTempl(n, process)
|
handleNestedTempl(n, process)
|
||||||
elif mode == sinkArg:
|
elif mode == sinkArg:
|
||||||
|
|
@ -748,7 +748,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
result = passCopyToSink(n, c, s)
|
result = passCopyToSink(n, c, s)
|
||||||
else:
|
else:
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkBracket, nkObjConstr, nkTupleConstr, nkClosure:
|
of nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkCurly:
|
||||||
# Let C(x) be the construction, 'x' the vector of arguments.
|
# Let C(x) be the construction, 'x' the vector of arguments.
|
||||||
# C(x) either owns 'x' or it doesn't.
|
# C(x) either owns 'x' or it doesn't.
|
||||||
# If C(x) owns its data, we must consume C(x).
|
# If C(x) owns its data, we must consume C(x).
|
||||||
|
|
@ -790,7 +790,9 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
|
|
||||||
result = shallowCopy(n)
|
result = shallowCopy(n)
|
||||||
for i in 1..<n.len:
|
for i in 1..<n.len:
|
||||||
if i < L and (isSinkTypeForParam(parameters[i]) or inSpawn > 0):
|
if i < L and isCompileTimeOnly(parameters[i]):
|
||||||
|
result[i] = n[i]
|
||||||
|
elif i < L and (isSinkTypeForParam(parameters[i]) or inSpawn > 0):
|
||||||
result[i] = p(n[i], c, s, sinkArg)
|
result[i] = p(n[i], c, s, sinkArg)
|
||||||
else:
|
else:
|
||||||
result[i] = p(n[i], c, s, normal)
|
result[i] = p(n[i], c, s, normal)
|
||||||
|
|
@ -867,8 +869,67 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef,
|
of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef,
|
||||||
nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
|
nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
|
||||||
nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
|
nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
|
||||||
nkExportStmt, nkPragma, nkCommentStmt, nkBreakState:
|
nkExportStmt, nkPragma, nkCommentStmt, nkBreakState, nkTypeOfExpr:
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
of nkStringToCString, nkCStringToString, nkChckRangeF, nkChckRange64, nkChckRange, nkPragmaBlock:
|
||||||
|
result = shallowCopy(n)
|
||||||
|
for i in 0 ..< n.len:
|
||||||
|
result[i] = p(n[i], c, s, normal)
|
||||||
|
if n.typ != nil and hasDestructor(n.typ):
|
||||||
|
if mode == normal:
|
||||||
|
result = ensureDestruction(result, c, s)
|
||||||
|
|
||||||
|
of nkHiddenSubConv, nkHiddenStdConv, nkConv:
|
||||||
|
# we have an "ownership invariance" for all constructors C(x).
|
||||||
|
# See the comment for nkBracket construction. If the caller wants
|
||||||
|
# to own 'C(x)', it really wants to own 'x' too. If it doesn't,
|
||||||
|
# we need to destroy 'x' but the function call handling ensures that
|
||||||
|
# already.
|
||||||
|
result = copyTree(n)
|
||||||
|
if n.typ.skipTypes(abstractInst-{tyOwned}).kind != tyOwned and
|
||||||
|
n[1].typ.skipTypes(abstractInst-{tyOwned}).kind == tyOwned:
|
||||||
|
# allow conversions from owned to unowned via this little hack:
|
||||||
|
let nTyp = n[1].typ
|
||||||
|
n[1].typ = n.typ
|
||||||
|
result[1] = p(n[1], c, s, mode)
|
||||||
|
result[1].typ = nTyp
|
||||||
|
else:
|
||||||
|
result[1] = p(n[1], c, s, mode)
|
||||||
|
|
||||||
|
of nkObjDownConv, nkObjUpConv:
|
||||||
|
result = copyTree(n)
|
||||||
|
result[0] = p(n[0], c, s, mode)
|
||||||
|
|
||||||
|
of nkDotExpr:
|
||||||
|
result = shallowCopy(n)
|
||||||
|
result[0] = p(n[0], c, s, normal)
|
||||||
|
for i in 1 ..< n.len:
|
||||||
|
result[i] = n[i]
|
||||||
|
if mode == sinkArg and hasDestructor(n.typ):
|
||||||
|
if isAnalysableFieldAccess(n, c.owner) and isLastRead(n, c):
|
||||||
|
s.wasMoved.add genWasMoved(n, c)
|
||||||
|
else:
|
||||||
|
result = passCopyToSink(result, c, s)
|
||||||
|
|
||||||
|
of nkBracketExpr, nkAddr, nkHiddenAddr, nkDerefExpr, nkHiddenDeref:
|
||||||
|
result = shallowCopy(n)
|
||||||
|
for i in 0 ..< n.len:
|
||||||
|
result[i] = p(n[i], c, s, normal)
|
||||||
|
if mode == sinkArg and hasDestructor(n.typ):
|
||||||
|
if isAnalysableFieldAccess(n, c.owner) and isLastRead(n, c):
|
||||||
|
# consider 'a[(g; destroy(g); 3)]', we want to say 'wasMoved(a[3])'
|
||||||
|
# without the junk, hence 'genWasMoved(n, c)'
|
||||||
|
# and not 'genWasMoved(result, c)':
|
||||||
|
s.wasMoved.add genWasMoved(n, c)
|
||||||
|
else:
|
||||||
|
result = passCopyToSink(result, c, s)
|
||||||
|
|
||||||
|
of nkDefer, nkRange:
|
||||||
|
result = shallowCopy(n)
|
||||||
|
for i in 0 ..< n.len:
|
||||||
|
result[i] = p(n[i], c, s, normal)
|
||||||
|
|
||||||
of nkBreakStmt:
|
of nkBreakStmt:
|
||||||
s.needsTry = true
|
s.needsTry = true
|
||||||
result = n
|
result = n
|
||||||
|
|
@ -886,10 +947,10 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
result[0] = p(n[0], c, s, mode)
|
result[0] = p(n[0], c, s, mode)
|
||||||
for i in 1..<n.len:
|
for i in 1..<n.len:
|
||||||
result[i] = n[i]
|
result[i] = n[i]
|
||||||
|
of nkGotoState, nkState:
|
||||||
|
result = n
|
||||||
else:
|
else:
|
||||||
result = shallowCopy(n)
|
internalError(c.graph.config, n.info, "cannot inject destructors to node kind: " & $n.kind)
|
||||||
for i in 0..<n.len:
|
|
||||||
result[i] = p(n[i], c, s, mode)
|
|
||||||
|
|
||||||
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
|
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
|
||||||
case ri.kind
|
case ri.kind
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue