diff options
Diffstat (limited to 'lib/core')
-rw-r--r-- | lib/core/seqs.nim | 10 | ||||
-rw-r--r-- | lib/core/strs.nim | 17 |
2 files changed, 14 insertions, 13 deletions
diff --git a/lib/core/seqs.nim b/lib/core/seqs.nim index 977b23b26..1a81b89ea 100644 --- a/lib/core/seqs.nim +++ b/lib/core/seqs.nim @@ -15,7 +15,7 @@ proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".} ## Default seq implementation used by Nim's core. type - NimSeqPayload {.core.}[T] = object + NimSeqPayload[T] = object cap: int region: Allocator data: UncheckedArray[T] @@ -40,6 +40,7 @@ proc `=destroy`[T](s: var seq[T]) = var x = cast[ptr NimSeqV2[T]](addr s) var p = x.p if p != nil: + mixin `=destroy` when not supportsCopyMem(T): for i in 0..<x.len: `=destroy`(p.data[i]) p.region.dealloc(p.region, p, payloadSize(p.cap)) @@ -47,11 +48,12 @@ proc `=destroy`[T](s: var seq[T]) = x.len = 0 proc `=`[T](x: var seq[T]; y: seq[T]) = + mixin `=destroy` var a = cast[ptr NimSeqV2[T]](addr x) var b = cast[ptr NimSeqV2[T]](unsafeAddr y) if a.p == b.p: return - `=destroy`(a) + `=destroy`(x) a.len = b.len if b.p != nil: a.p = cast[type(a.p)](alloc(payloadSize(a.len))) @@ -63,10 +65,11 @@ proc `=`[T](x: var seq[T]; y: seq[T]) = a.p.data[i] = b.p.data[i] proc `=sink`[T](x: var seq[T]; y: seq[T]) = + mixin `=destroy` var a = cast[ptr NimSeqV2[T]](addr x) var b = cast[ptr NimSeqV2[T]](unsafeAddr y) if a.p != nil and a.p != b.p: - `=destroy`(a) + `=destroy`(x) a.len = b.len a.p = b.p @@ -109,6 +112,7 @@ proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize: int): pointer {. result = q proc shrink*[T](x: var seq[T]; newLen: Natural) = + mixin `=destroy` sysAssert newLen <= x.len, "invalid newLen parameter for 'shrink'" when not supportsCopyMem(T): for i in countdown(x.len - 1, newLen - 1): diff --git a/lib/core/strs.nim b/lib/core/strs.nim index 186add52a..ccbde76fe 100644 --- a/lib/core/strs.nim +++ b/lib/core/strs.nim @@ -51,15 +51,12 @@ proc `=destroy`(s: var string) = a.len = 0 a.p = nil -template lose(a) = - frees(a) - proc `=sink`(x: var string, y: string) = var a = cast[ptr NimStringV2](addr x) var b = cast[ptr NimStringV2](unsafeAddr y) # we hope this is optimized away for not yet alive objects: if unlikely(a.p == b.p): return - lose(a) + frees(a) a.len = b.len a.p = b.p @@ -67,13 +64,13 @@ proc `=`(x: var string, y: string) = var a = cast[ptr NimStringV2](addr x) var b = cast[ptr NimStringV2](unsafeAddr y) if unlikely(a.p == b.p): return - lose(a) + frees(a) a.len = b.len if isLiteral(b): # we can shallow copy literals: a.p = b.p else: - let region = if a.p.region != nil: a.p.region else: getLocalAllocator() + let region = if a.p != nil and a.p.region != nil: a.p.region else: getLocalAllocator() # we have to allocate the 'cap' here, consider # 'let y = newStringOfCap(); var x = y' # on the other hand... These get turned into moves now. @@ -136,6 +133,7 @@ proc appendString(dest: var NimStringV2; src: NimStringV2) {.compilerproc, inlin if src.len > 0: # also copy the \0 terminator: copyMem(unsafeAddr dest.p.data[dest.len], unsafeAddr src.p.data[0], src.len+1) + inc dest.len, src.len proc appendChar(dest: var NimStringV2; c: char) {.compilerproc, inline.} = dest.p.data[dest.len] = c @@ -166,7 +164,6 @@ proc mnewString(len: int): NimStringV2 {.compilerProc.} = proc setLengthStrV2(s: var NimStringV2, newLen: int) {.compilerRtl.} = if newLen > s.len: prepareAdd(s, newLen - s.len) - else: - s.len = newLen - # this also only works because the destructor - # looks at s.p and not s.len + s.len = newLen + # this also only works because the destructor + # looks at s.p and not s.len |