more progress on destructors; removed old destructor based code as it proved confusing
This commit is contained in:
parent
255902f9a5
commit
fa92c519aa
9 changed files with 152 additions and 270 deletions
101
tests/destructor/tatomicptrs.nim
Normal file
101
tests/destructor/tatomicptrs.nim
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
discard """
|
||||
output: '''allocating
|
||||
allocating
|
||||
allocating
|
||||
55
|
||||
60
|
||||
99
|
||||
deallocating
|
||||
deallocating
|
||||
deallocating
|
||||
'''
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
"""
|
||||
|
||||
type
|
||||
SharedPtr*[T] = object
|
||||
x: ptr T
|
||||
|
||||
#proc isNil[T](s: SharedPtr[T]): bool {.inline.} = s.x.isNil
|
||||
|
||||
template incRef(x) =
|
||||
atomicInc(x.refcount)
|
||||
|
||||
template decRef(x): untyped = atomicDec(x.refcount)
|
||||
|
||||
proc makeShared*[T](x: T): SharedPtr[T] =
|
||||
# XXX could benefit from 'sink' parameter.
|
||||
# XXX could benefit from a macro that generates it.
|
||||
result = cast[SharedPtr[T]](allocShared(sizeof(x)))
|
||||
result.x[] = x
|
||||
echo "allocating"
|
||||
|
||||
proc `=destroy`*[T](dest: var SharedPtr[T]) =
|
||||
var s = dest.x
|
||||
if s != nil and decRef(s) == 0:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
dest.x = nil
|
||||
|
||||
proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
|
||||
var s = src.x
|
||||
if s != nil: incRef(s)
|
||||
#atomicSwap(dest, s)
|
||||
# XXX use an atomic store here:
|
||||
swap(dest.x, s)
|
||||
if s != nil and decRef(s) == 0:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
|
||||
proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
|
||||
## XXX make this an atomic store:
|
||||
if dest.x != src.x:
|
||||
let s = dest.x
|
||||
if s != nil:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
dest.x = src.x
|
||||
|
||||
template `.`*[T](s: SharedPtr[T]; field: untyped): untyped =
|
||||
s.x.field
|
||||
|
||||
template `.=`*[T](s: SharedPtr[T]; field, value: untyped) =
|
||||
s.x.field = value
|
||||
|
||||
from macros import unpackVarargs
|
||||
|
||||
template `.()`*[T](s: SharedPtr[T]; field: untyped, args: varargs[untyped]): untyped =
|
||||
unpackVarargs(s.x.field, args)
|
||||
|
||||
|
||||
type
|
||||
Tree = SharedPtr[TreeObj]
|
||||
TreeObj = object
|
||||
refcount: int
|
||||
le, ri: Tree
|
||||
data: int
|
||||
|
||||
proc takesTree(a: Tree) =
|
||||
if not a.isNil:
|
||||
takesTree(a.le)
|
||||
echo a.data
|
||||
takesTree(a.ri)
|
||||
|
||||
proc createTree(data: int): Tree =
|
||||
result = makeShared(TreeObj(refcount: 1, data: data))
|
||||
|
||||
proc createTree(data: int; le, ri: Tree): Tree =
|
||||
result = makeShared(TreeObj(refcount: 1, le: le, ri: ri, data: data))
|
||||
|
||||
|
||||
proc main =
|
||||
let le = createTree(55)
|
||||
let ri = createTree(99)
|
||||
let t = createTree(60, le, ri)
|
||||
takesTree(t)
|
||||
|
||||
main()
|
||||
|
||||
|
|
@ -20,10 +20,10 @@ myobj destroyed
|
|||
----
|
||||
myobj destroyed
|
||||
'''
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
{.experimental.}
|
||||
|
||||
type
|
||||
TMyObj = object
|
||||
x, y: int
|
||||
|
|
@ -61,7 +61,7 @@ proc `=destroy`(o: var TMyObj) =
|
|||
if o.p != nil: dealloc o.p
|
||||
echo "myobj destroyed"
|
||||
|
||||
proc `=destroy`(o: var TMyGeneric1) =
|
||||
proc `=destroy`(o: var TMyGeneric1[int]) =
|
||||
echo "mygeneric1 destroyed"
|
||||
|
||||
proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) =
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
discard """
|
||||
line: 23
|
||||
nimout: " usage of a type with a destructor in a non destructible context"
|
||||
"""
|
||||
|
||||
{.experimental.}
|
||||
|
||||
type
|
||||
TMyObj = object
|
||||
x, y: int
|
||||
p: pointer
|
||||
|
||||
proc `=destroy`(o: var TMyObj) =
|
||||
if o.p != nil: dealloc o.p
|
||||
|
||||
proc open: TMyObj =
|
||||
result = TMyObj(x: 1, y: 2, p: alloc(3))
|
||||
|
||||
|
||||
proc `$`(x: TMyObj): string = $x.y
|
||||
|
||||
proc foo =
|
||||
discard open()
|
||||
|
||||
# XXX doesn't trigger this yet:
|
||||
#echo open()
|
||||
|
||||
|
|
@ -2,14 +2,14 @@ discard """
|
|||
output: '''assign
|
||||
destroy
|
||||
destroy
|
||||
destroy Foo: 5
|
||||
5
|
||||
destroy Foo: 123
|
||||
123'''
|
||||
123
|
||||
destroy Foo: 5
|
||||
destroy Foo: 123'''
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
"""
|
||||
|
||||
# bug #2821
|
||||
{.experimental.}
|
||||
|
||||
type T = object
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue