--gc:destructors: baby steps
This commit is contained in:
parent
446f911a17
commit
e3a668a33b
5 changed files with 27 additions and 25 deletions
|
|
@ -296,7 +296,8 @@ proc makePtrType(c: Con, baseType: PType): PType =
|
||||||
template genOp(opr, opname, ri) =
|
template genOp(opr, opname, ri) =
|
||||||
let op = opr
|
let op = opr
|
||||||
if op == nil:
|
if op == nil:
|
||||||
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t))
|
globalError(c.graph.config, dest.info, "internal error: '" & opname &
|
||||||
|
"' operator not found for type " & typeToString(t))
|
||||||
elif op.ast[genericParamsPos].kind != nkEmpty:
|
elif op.ast[genericParamsPos].kind != nkEmpty:
|
||||||
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
|
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
|
||||||
patchHead op
|
patchHead op
|
||||||
|
|
@ -365,7 +366,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode =
|
||||||
result.add genWasMoved(n, c)
|
result.add genWasMoved(n, c)
|
||||||
result.add tempAsNode
|
result.add tempAsNode
|
||||||
|
|
||||||
proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
|
proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
|
||||||
assert s.kind == nkSym and s.sym.kind == skParam
|
assert s.kind == nkSym and s.sym.kind == skParam
|
||||||
if not isLastRead(s, c):
|
if not isLastRead(s, c):
|
||||||
localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
|
localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
|
||||||
|
|
@ -427,7 +428,7 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
result = copyNode(arg)
|
result = copyNode(arg)
|
||||||
for i in 0..<arg.len:
|
for i in 0..<arg.len:
|
||||||
var branch = copyNode(arg[i])
|
var branch = copyNode(arg[i])
|
||||||
if arg[i].kind in {nkElifBranch, nkElifExpr}:
|
if arg[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
branch.add p(arg[i][0], c)
|
branch.add p(arg[i][0], c)
|
||||||
branch.add pArgIfTyped(arg[i][1])
|
branch.add pArgIfTyped(arg[i][1])
|
||||||
else:
|
else:
|
||||||
|
|
@ -442,13 +443,13 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
branch = arg[i] # of branch conditions are constants
|
branch = arg[i] # of branch conditions are constants
|
||||||
branch[^1] = pArgIfTyped(arg[i][^1])
|
branch[^1] = pArgIfTyped(arg[i][^1])
|
||||||
elif arg[i].kind in {nkElifBranch, nkElifExpr}:
|
elif arg[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
branch = copyNode(arg[i])
|
branch = copyNode(arg[i])
|
||||||
branch.add p(arg[i][0], c)
|
branch.add p(arg[i][0], c)
|
||||||
branch.add pArgIfTyped(arg[i][1])
|
branch.add pArgIfTyped(arg[i][1])
|
||||||
else:
|
else:
|
||||||
branch = copyNode(arg[i])
|
branch = copyNode(arg[i])
|
||||||
branch.add pArgIfTyped(arg[i][0])
|
branch.add pArgIfTyped(arg[i][0])
|
||||||
result.add branch
|
result.add branch
|
||||||
else:
|
else:
|
||||||
# an object that is not temporary but passed to a 'sink' parameter
|
# an object that is not temporary but passed to a 'sink' parameter
|
||||||
# results in a copy.
|
# results in a copy.
|
||||||
|
|
@ -476,7 +477,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
result.add ri2
|
result.add ri2
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym):
|
if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym):
|
||||||
# unpacking of tuple: move out the elements
|
# unpacking of tuple: move out the elements
|
||||||
result = genSink(c, dest.typ, dest, ri)
|
result = genSink(c, dest.typ, dest, ri)
|
||||||
else:
|
else:
|
||||||
result = genCopy(c, dest.typ, dest, ri)
|
result = genCopy(c, dest.typ, dest, ri)
|
||||||
|
|
@ -509,11 +510,11 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
branch = ri[i] # of branch conditions are constants
|
branch = ri[i] # of branch conditions are constants
|
||||||
branch[^1] = moveOrCopyIfTyped(ri[i][^1])
|
branch[^1] = moveOrCopyIfTyped(ri[i][^1])
|
||||||
elif ri[i].kind in {nkElifBranch, nkElifExpr}:
|
elif ri[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
branch = copyNode(ri[i])
|
branch = copyNode(ri[i])
|
||||||
branch.add p(ri[i][0], c)
|
branch.add p(ri[i][0], c)
|
||||||
branch.add moveOrCopyIfTyped(ri[i][1])
|
branch.add moveOrCopyIfTyped(ri[i][1])
|
||||||
else:
|
else:
|
||||||
branch = copyNode(ri[i])
|
branch = copyNode(ri[i])
|
||||||
branch.add moveOrCopyIfTyped(ri[i][0])
|
branch.add moveOrCopyIfTyped(ri[i][0])
|
||||||
result.add branch
|
result.add branch
|
||||||
of nkBracket:
|
of nkBracket:
|
||||||
|
|
@ -550,7 +551,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
sinkParamIsLastReadCheck(c, ri)
|
sinkParamIsLastReadCheck(c, ri)
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
snk.add ri
|
snk.add ri
|
||||||
result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
|
result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
|
||||||
elif ri.sym.kind != skParam and isLastRead(ri, c):
|
elif ri.sym.kind != skParam and isLastRead(ri, c):
|
||||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
var snk = genSink(c, dest.typ, dest, ri)
|
var snk = genSink(c, dest.typ, dest, ri)
|
||||||
|
|
@ -647,7 +648,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||||
let params = owner.typ.n
|
let params = owner.typ.n
|
||||||
for i in 1 ..< params.len:
|
for i in 1 ..< params.len:
|
||||||
let param = params[i].sym
|
let param = params[i].sym
|
||||||
if param.typ.kind == tySink and hasDestructor(param.typ):
|
if param.typ.kind == tySink and hasDestructor(param.typ):
|
||||||
c.destroys.add genDestroy(c, param.typ.skipTypes({tyGenericInst, tyAlias, tySink}), params[i])
|
c.destroys.add genDestroy(c, param.typ.skipTypes({tyGenericInst, tyAlias, tySink}), params[i])
|
||||||
|
|
||||||
let body = p(n, c)
|
let body = p(n, c)
|
||||||
|
|
|
||||||
|
|
@ -1427,6 +1427,12 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
||||||
addResult(c, s.typ.sons[0], n.info, s.kind)
|
addResult(c, s.typ.sons[0], n.info, s.kind)
|
||||||
addResultNode(c, n)
|
addResultNode(c, n)
|
||||||
|
|
||||||
|
proc canonType(c: PContext, t: PType): PType =
|
||||||
|
if t.kind == tySequence:
|
||||||
|
result = c.graph.sysTypes[tySequence]
|
||||||
|
else:
|
||||||
|
result = t
|
||||||
|
|
||||||
proc semOverride(c: PContext, s: PSym, n: PNode) =
|
proc semOverride(c: PContext, s: PSym, n: PNode) =
|
||||||
case s.name.s.normalize
|
case s.name.s.normalize
|
||||||
of "=destroy":
|
of "=destroy":
|
||||||
|
|
@ -1440,6 +1446,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
||||||
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
|
||||||
else: break
|
else: break
|
||||||
if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
|
if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
|
||||||
|
obj = canonType(c, obj)
|
||||||
if obj.destructor.isNil:
|
if obj.destructor.isNil:
|
||||||
obj.destructor = s
|
obj.destructor = s
|
||||||
else:
|
else:
|
||||||
|
|
@ -1491,6 +1498,8 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
|
||||||
objB = objB.sons[0]
|
objB = objB.sons[0]
|
||||||
else: break
|
else: break
|
||||||
if obj.kind in {tyObject, tyDistinct, tySequence, tyString} and sameType(obj, objB):
|
if obj.kind in {tyObject, tyDistinct, tySequence, tyString} and sameType(obj, objB):
|
||||||
|
# attach these ops to the canonical tySequence
|
||||||
|
obj = canonType(c, obj)
|
||||||
let opr = if s.name.s == "=": addr(obj.assignment) else: addr(obj.sink)
|
let opr = if s.name.s == "=": addr(obj.assignment) else: addr(obj.sink)
|
||||||
if opr[].isNil:
|
if opr[].isNil:
|
||||||
opr[] = s
|
opr[] = s
|
||||||
|
|
|
||||||
|
|
@ -1551,10 +1551,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
# XXX figure out why this has children already...
|
# XXX figure out why this has children already...
|
||||||
result.sons.setLen 0
|
result.sons.setLen 0
|
||||||
result.n = nil
|
result.n = nil
|
||||||
if c.config.selectedGc == gcDestructors:
|
result.flags = {tfHasAsgn}
|
||||||
result.flags = {tfHasAsgn}
|
|
||||||
else:
|
|
||||||
result.flags = {}
|
|
||||||
semContainerArg(c, n, "seq", result)
|
semContainerArg(c, n, "seq", result)
|
||||||
else:
|
else:
|
||||||
result = semContainer(c, n, tySequence, "seq", prev)
|
result = semContainer(c, n, tySequence, "seq", prev)
|
||||||
|
|
|
||||||
|
|
@ -70,12 +70,6 @@ proc `=sink`[T](x: var seq[T]; y: seq[T]) =
|
||||||
a.len = b.len
|
a.len = b.len
|
||||||
a.p = b.p
|
a.p = b.p
|
||||||
|
|
||||||
when false:
|
|
||||||
proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerProc.}
|
|
||||||
proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
|
||||||
compilerRtl.}
|
|
||||||
proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.}
|
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
PayloadBase = object
|
PayloadBase = object
|
||||||
|
|
|
||||||
|
|
@ -3431,6 +3431,10 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
when defined(memtracker):
|
when defined(memtracker):
|
||||||
include "system/memtracker"
|
include "system/memtracker"
|
||||||
|
|
||||||
|
when defined(gcDestructors):
|
||||||
|
include "core/strs"
|
||||||
|
include "core/seqs"
|
||||||
|
|
||||||
when hostOS == "standalone":
|
when hostOS == "standalone":
|
||||||
include "system/embedded"
|
include "system/embedded"
|
||||||
else:
|
else:
|
||||||
|
|
@ -3479,10 +3483,7 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
{.pop.}
|
{.pop.}
|
||||||
{.push stack_trace: off, profiler:off.}
|
{.push stack_trace: off, profiler:off.}
|
||||||
when hasAlloc:
|
when hasAlloc:
|
||||||
when defined(gcDestructors):
|
when not defined(gcDestructors):
|
||||||
include "core/strs"
|
|
||||||
include "core/seqs"
|
|
||||||
else:
|
|
||||||
include "system/sysstr"
|
include "system/sysstr"
|
||||||
{.pop.}
|
{.pop.}
|
||||||
when hasAlloc: include "system/strmantle"
|
when hasAlloc: include "system/strmantle"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue