summary refs log tree commit diff stats
path: root/tests/destructor/tatomicptrs.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/destructor/tatomicptrs.nim')
-rw-r--r--tests/destructor/tatomicptrs.nim85
1 files changed, 80 insertions, 5 deletions
diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim
index d20596415..82870ac82 100644
--- a/tests/destructor/tatomicptrs.nim
+++ b/tests/destructor/tatomicptrs.nim
@@ -8,8 +8,10 @@ allocating
 deallocating
 deallocating
 deallocating
+allocating
+deallocating
 '''
-  cmd: '''nim c --newruntime $file'''
+joinable: false
 """
 
 type
@@ -23,10 +25,9 @@ template incRef(x) =
 
 template decRef(x): untyped = atomicDec(x.refcount)
 
-proc makeShared*[T](x: T): SharedPtr[T] =
-  # XXX could benefit from 'sink' parameter.
+proc makeShared*[T](x: sink T): SharedPtr[T] =
   # XXX could benefit from a macro that generates it.
-  result = cast[SharedPtr[T]](allocShared(sizeof(x)))
+  result = cast[SharedPtr[T]](allocShared0(sizeof(x)))
   result.x[] = x
   echo "allocating"
 
@@ -38,7 +39,7 @@ proc `=destroy`*[T](dest: var SharedPtr[T]) =
     echo "deallocating"
     dest.x = nil
 
-proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
+proc `=copy`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
   var s = src.x
   if s != nil: incRef(s)
   #atomicSwap(dest, s)
@@ -49,6 +50,9 @@ proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
     deallocShared(s)
     echo "deallocating"
 
+proc `=dup`*[T](src: SharedPtr[T]): SharedPtr[T] =
+  `=copy`(result, src)
+
 proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
   ## XXX make this an atomic store:
   if dest.x != src.x:
@@ -59,6 +63,9 @@ proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
       echo "deallocating"
     dest.x = src.x
 
+proc get*[T](s: SharedPtr[T]): lent T =
+  s.x[]
+
 template `.`*[T](s: SharedPtr[T]; field: untyped): untyped =
   s.x.field
 
@@ -68,6 +75,7 @@ template `.=`*[T](s: SharedPtr[T]; field, value: untyped) =
 from macros import unpackVarargs
 
 template `.()`*[T](s: SharedPtr[T]; field: untyped, args: varargs[untyped]): untyped =
+  # xxx this isn't used, the test should be improved
   unpackVarargs(s.x.field, args)
 
 
@@ -99,3 +107,70 @@ proc main =
 
 main()
 
+
+
+#-------------------------------------------------------
+#bug #9781
+
+type
+  MySeq* [T] = object
+    refcount: int
+    len: int
+    data: ptr UncheckedArray[T]
+
+proc `=destroy`*[T](m: var MySeq[T]) {.inline.} =
+  if m.data != nil:
+    deallocShared(m.data)
+    m.data = nil
+
+proc `=copy`*[T](m: var MySeq[T], m2: MySeq[T]) =
+  if m.data == m2.data: return
+  if m.data != nil:
+    `=destroy`(m)
+
+  m.len = m2.len
+  let bytes = m.len.int * sizeof(float)
+  if bytes > 0:
+    m.data = cast[ptr UncheckedArray[T]](allocShared(bytes))
+    copyMem(m.data, m2.data, bytes)
+
+proc `=dup`*[T](m: MySeq[T]): MySeq[T] =
+  `=copy`[T](result, m)
+
+proc `=sink`*[T](m: var MySeq[T], m2: MySeq[T]) {.inline.} =
+  if m.data != m2.data:
+    if m.data != nil:
+      `=destroy`(m)
+    m.len = m2.len
+    m.data = m2.data
+    m.refcount = m2.refcount
+
+proc len*[T](m: MySeq[T]): int {.inline.} = m.len
+
+proc newMySeq*[T](size: int, initial_value: T): MySeq[T] =
+  result.len = size
+  result.refcount = 1
+  if size > 0:
+    result.data = cast[ptr UncheckedArray[T]](allocShared(sizeof(T) * size))
+
+
+let x = makeShared(newMySeq(10, 1.0))
+doAssert: x.get().len == 10
+
+
+
+#-------------------------------------------------------
+#bug #12882
+
+type
+  ValueObject = object
+    v: MySeq[int]
+    name: string
+
+  TopObject = object
+    internal: seq[ValueObject]
+
+var zz = new(TopObject)
+
+
+