summary refs log tree commit diff stats
path: root/tests/destructor/tatomicptrs.nim
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2018-11-26 08:45:45 +0000
committerAndreas Rumpf <rumpf_a@web.de>2018-11-26 09:45:45 +0100
commit2ac7f523889a39bf1e4c17af90686e33b9a65883 (patch)
treedd707bccd36dc988a5b6937b12d5da16e6417ff1 /tests/destructor/tatomicptrs.nim
parent410fd1deae95ecc9fd146fc2c8e6cc0cd24bfee7 (diff)
downloadNim-2ac7f523889a39bf1e4c17af90686e33b9a65883.tar.gz
Fixes multiple bugs with sink arguments (#9802)
* fixes #9781

* fix spacing
Diffstat (limited to 'tests/destructor/tatomicptrs.nim')
-rw-r--r--tests/destructor/tatomicptrs.nim52
1 files changed, 50 insertions, 2 deletions
diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim
index d20596415..fd8fc34d9 100644
--- a/tests/destructor/tatomicptrs.nim
+++ b/tests/destructor/tatomicptrs.nim
@@ -8,6 +8,8 @@ allocating
 deallocating
 deallocating
 deallocating
+allocating
+deallocating
 '''
   cmd: '''nim c --newruntime $file'''
 """
@@ -23,8 +25,7 @@ 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.x[] = x
@@ -59,6 +60,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
 
@@ -99,3 +103,47 @@ 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 `=`*[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 `=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
+
+proc len*[T](m: MySeq[T]): int {.inline.} = m.len
+
+proc newMySeq*[T](size: int, initial_value: T): MySeq[T] =
+  result.len = size
+  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