arc: =deepcopy fixes

This commit is contained in:
Araq
2020-09-20 09:01:42 +02:00
committed by Andreas Rumpf
parent ebb632ccba
commit 33be7c6f5e
3 changed files with 81 additions and 6 deletions

View File

@@ -459,7 +459,6 @@ proc traverse(c: var Partitions; n: PNode) =
if paramType.kind == tyVar:
if c.inNoSideEffectSection == 0:
for r in roots: potentialMutation(c, r, it.info)
else:
for r in roots: noCursor(c, r)
of nkAddr, nkHiddenAddr:

View File

@@ -140,7 +140,10 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
unsureAsgnRef(cast[PPointer](dest), s2)
elif mt.base.deepcopy != nil:
let z = mt.base.deepcopy(s2)
unsureAsgnRef(cast[PPointer](dest), z)
when defined(nimSeqsV2):
cast[PPointer](dest)[] = z
else:
unsureAsgnRef(cast[PPointer](dest), z)
else:
let z = tab.get(s2)
if z == nil:
@@ -157,10 +160,16 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
let x = usrToCell(s2)
let realType = x.typ
sysAssert realType == mt, " types do differ"
# this version should work for any possible GC:
let typ = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[] else: mt.base
let z = when defined(nimSeqsV2): nimNewObj(typ.size) else: newObj(mt, typ.size)
unsureAsgnRef(cast[PPointer](dest), z)
when defined(nimSeqsV2):
let typ = if mt.base.kind == tyObject: cast[PNimType](cast[ptr PNimTypeV2](s2)[].typeInfoV1)
else: mt.base
let z = nimNewObj(typ.size)
cast[PPointer](dest)[] = z
else:
# this version should work for any other GC:
let typ = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[] else: mt.base
let z = newObj(mt, typ.size)
unsureAsgnRef(cast[PPointer](dest), z)
tab.put(s2, z)
genericDeepCopyAux(z, s2, typ, tab)
else:

67
tests/arc/tdeepcopy.nim Normal file
View File

@@ -0,0 +1,67 @@
discard """
cmd: "nim c --gc:arc $file"
output: '''13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
13 abc
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
called deepCopy for int
0'''
"""
type
PBinaryTree = ref object of RootObj
le, ri: PBinaryTree
value: int
proc mainB =
var x: PBinaryTree
deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13))))
var y: string
deepCopy y, "abc"
echo x.ri.le.value, " ", y
for i in 0..10:
mainB()
type
Bar[T] = object
x: T
proc `=deepCopy`[T](b: ref Bar[T]): ref Bar[T] =
result.new
result.x = b.x
when T is int:
echo "called deepCopy for int"
else:
echo "called deepCopy for something else"
proc main =
var dummy, c: ref Bar[int]
new(dummy)
dummy.x = 44
deepCopy c, dummy
for i in 0..10:
main()
echo getOccupiedMem()