diff options
author | Araq <rumpf_a@web.de> | 2019-04-22 10:11:37 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-04-22 10:11:37 +0200 |
commit | 4f9366975441be889a8cd4fbfb4e41f6830dc542 (patch) | |
tree | f69285c7ae4c16807b475fdbeb2cb1a50a0f9da4 | |
parent | 0194f4346755b4d215cb79625227f7ee46f11f43 (diff) | |
download | Nim-4f9366975441be889a8cd4fbfb4e41f6830dc542.tar.gz |
fixes #11065
-rw-r--r-- | lib/core/seqs.nim | 27 | ||||
-rw-r--r-- | tests/destructor/tgcdestructors.nim | 22 |
2 files changed, 40 insertions, 9 deletions
diff --git a/lib/core/seqs.nim b/lib/core/seqs.nim index a79f0c2f5..5483c0ebc 100644 --- a/lib/core/seqs.nim +++ b/lib/core/seqs.nim @@ -104,6 +104,10 @@ proc newSeqPayload(cap, elemSize: int): pointer {.compilerRtl, raises: [].} = proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize: int): pointer {. compilerRtl, noSideEffect, raises: [].} = {.noSideEffect.}: + template `+!`(p: pointer, s: int): pointer = + cast[pointer](cast[int](p) +% s) + + const headerSize = sizeof(int) + sizeof(Allocator) if addlen <= 0: result = p elif p == nil: @@ -112,14 +116,23 @@ proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize: int): pointer {. # Note: this means we cannot support things that have internal pointers as # they get reallocated here. This needs to be documented clearly. var p = cast[ptr PayloadBase](p) - let allocator = if p.allocator == nil: getLocalAllocator() else: p.allocator let cap = max(resize(p.cap), len+addlen) - var q = cast[ptr PayloadBase](allocator.realloc(allocator, p, - sizeof(int) + sizeof(Allocator) + elemSize * p.cap, - sizeof(int) + sizeof(Allocator) + elemSize * cap)) - q.allocator = allocator - q.cap = cap - result = q + if p.allocator == nil: + let allocator = getLocalAllocator() + var q = cast[ptr PayloadBase](allocator.alloc(allocator, + headerSize + elemSize * cap)) + copyMem(q +! headerSize, p +! headerSize, len * elemSize) + q.allocator = allocator + q.cap = cap + result = q + else: + let allocator = p.allocator + var q = cast[ptr PayloadBase](allocator.realloc(allocator, p, + headerSize + elemSize * p.cap, + headerSize + elemSize * cap)) + q.allocator = allocator + q.cap = cap + result = q proc shrink*[T](x: var seq[T]; newLen: Natural) = mixin `=destroy` diff --git a/tests/destructor/tgcdestructors.nim b/tests/destructor/tgcdestructors.nim index c0a88e650..bc9f57d20 100644 --- a/tests/destructor/tgcdestructors.nim +++ b/tests/destructor/tgcdestructors.nim @@ -5,7 +5,8 @@ ho ha @["arg", "asdfklasdfkl", "asdkfj", "dfasj", "klfjl"] @[1, 2, 3] -25 25''' +@["red", "yellow", "orange", "rtrt1", "pink"] +30 30''' """ import allocators @@ -139,7 +140,7 @@ type Obj* = object f*: seq[int] -method main(o: Obj) = +method main(o: Obj) {.base.} = for newb in o.f: discard @@ -151,6 +152,23 @@ proc testforNoMove = testforNoMove() +# bug #11065 +type + Warm = seq[string] + +proc testWarm = + var w: Warm + w = @["red", "yellow", "orange"] + + var x = "rt" + var y = "rt1" + w.add(x & y) + + w.add("pink") + echo w + +testWarm() + #echo s let (a, d) = allocCounters() discard cprintf("%ld %ld\n", a, d) |