mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
progress
This commit is contained in:
@@ -1616,7 +1616,10 @@ when not defined(js) and defined(nimV2):
|
||||
proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
|
||||
|
||||
when notJSnotNims and defined(nimSeqsV2):
|
||||
include "system/strs_v2"
|
||||
when defined(nimSeqsV3):
|
||||
include "system/strs_v3"
|
||||
else:
|
||||
include "system/strs_v2"
|
||||
include "system/seqs_v2"
|
||||
|
||||
when not defined(js):
|
||||
@@ -1679,7 +1682,11 @@ when not defined(js):
|
||||
result = newString(len)
|
||||
else:
|
||||
result = newStringOfCap(len)
|
||||
when defined(nimSeqsV2):
|
||||
when defined(nimSeqsV3):
|
||||
let s = cast[ptr NimStringV3](addr result)
|
||||
if len > 0:
|
||||
s.len = len
|
||||
elif defined(nimSeqsV2):
|
||||
let s = cast[ptr NimStringV2](addr result)
|
||||
if len > 0:
|
||||
s.len = len
|
||||
|
||||
@@ -61,7 +61,11 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
|
||||
sysAssert(mt != nil, "genericAssignAux 2")
|
||||
case mt.kind
|
||||
of tyString:
|
||||
when defined(nimSeqsV2):
|
||||
when defined(nimSeqsV3):
|
||||
var x = cast[ptr NimStringV3](dest)
|
||||
var s2 = cast[ptr NimStringV3](s)[]
|
||||
nimAsgnStrV2(x[], s2)
|
||||
elif defined(nimSeqsV2):
|
||||
var x = cast[ptr NimStringV2](dest)
|
||||
var s2 = cast[ptr NimStringV2](s)[]
|
||||
nimAsgnStrV2(x[], s2)
|
||||
@@ -244,7 +248,11 @@ proc genericReset(dest: pointer, mt: PNimType) =
|
||||
of tyRef:
|
||||
unsureAsgnRef(cast[PPointer](dest), nil)
|
||||
of tyString:
|
||||
when defined(nimSeqsV2):
|
||||
when defined(nimSeqsV3):
|
||||
var s = cast[ptr NimStringV3](dest)
|
||||
frees(s[])
|
||||
zeroMem(dest, mt.size)
|
||||
elif defined(nimSeqsV2):
|
||||
var s = cast[ptr NimStringV2](dest)
|
||||
frees(s[])
|
||||
zeroMem(dest, mt.size)
|
||||
|
||||
@@ -90,7 +90,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
||||
sysAssert(mt != nil, "genericDeepCopyAux 2")
|
||||
case mt.kind
|
||||
of tyString:
|
||||
when defined(nimSeqsV2):
|
||||
when defined(nimSeqsV3):
|
||||
var x = cast[ptr NimStringV3](dest)
|
||||
var s2 = cast[ptr NimStringV3](s)[]
|
||||
nimAsgnStrV2(x[], s2)
|
||||
elif defined(nimSeqsV2):
|
||||
var x = cast[ptr NimStringV2](dest)
|
||||
var s2 = cast[ptr NimStringV2](s)[]
|
||||
nimAsgnStrV2(x[], s2)
|
||||
|
||||
@@ -11,25 +11,29 @@
|
||||
|
||||
type
|
||||
NimStrPayloadBase = object
|
||||
## cap lives at the negative offset of p: p - wordSize
|
||||
cap: int
|
||||
|
||||
NimStrPayload {.core.} = object
|
||||
data: UncheckedArray[char]
|
||||
|
||||
NimStringV3 {.core.} = object
|
||||
rawlen: int ## the lowest bit is used to indict whether it's a const or intern string
|
||||
## TODO: would it be better to use distinct?
|
||||
p: ptr UncheckedArray[char] ## can be nil if len == 0.
|
||||
## cap lives at the negative offset
|
||||
## cap lives at the negative offset of p: p - wordSize
|
||||
## non-zero terminated
|
||||
|
||||
const nimStrVersion {.core.} = 3
|
||||
|
||||
template isLiteral(s): bool = (s.rawlen and 1) == 1
|
||||
|
||||
template head(p: pointer): pointer =
|
||||
cast[pointer](cast[int](p) -% sizeof(NimStrPayloadBase))
|
||||
|
||||
|
||||
template cap(p: pointer): int =
|
||||
cast[ptr NimStrPayloadBase](cast[int](p) -% sizeof(NimStrPayloadBase))[].cap
|
||||
cast[ptr NimStrPayloadBase](head(p))[].cap
|
||||
|
||||
template `cap=`(p: pointer, size: int) =
|
||||
cast[ptr NimStrPayloadBase](cast[int](p) -% sizeof(NimStrPayloadBase))[].cap = size
|
||||
cast[ptr NimStrPayloadBase](head(p))[].cap = size
|
||||
|
||||
|
||||
template len(s: NimStringV3): int = s.rawlen shr 1
|
||||
@@ -41,24 +45,25 @@ proc markIntern(s: var NimStringV3): bool =
|
||||
s.rawlen = s.rawlen or 1
|
||||
result = not isLiteral(s)
|
||||
|
||||
proc unsafeUnmarkIntern(s: NimStringV3) =
|
||||
proc unsafeUnmarkIntern(s: var NimStringV3) =
|
||||
s.rawlen = s.rawlen and (not 1) # unmark?
|
||||
when compileOption("threads"):
|
||||
deallocShared(s.p -% sizeof(NimStrPayloadBase))
|
||||
deallocShared(head(s.p))
|
||||
else:
|
||||
dealloc(s.p -% sizeof(NimStrPayloadBase))
|
||||
dealloc(head(s.p))
|
||||
|
||||
template contentSize(cap): int = cap + sizeof(NimStrPayloadBase)
|
||||
|
||||
template frees(s) =
|
||||
if not isLiteral(s):
|
||||
when compileOption("threads"):
|
||||
deallocShared(s.p -% sizeof(NimStrPayloadBase))
|
||||
deallocShared(head(s.p))
|
||||
else:
|
||||
dealloc(s.p -% sizeof(NimStrPayloadBase))
|
||||
dealloc(head(s.p))
|
||||
|
||||
template allocPayload(newLen: int): ptr UncheckedArray[char] =
|
||||
when compileOption("threads"):
|
||||
cast[ptr UncheckedArray[char]](allocShared(contentSize(newLen) +! sizeof(NimStrPayloadBase)))
|
||||
cast[ptr UncheckedArray[char]](allocShared(contentSize(newLen)) +! sizeof(NimStrPayloadBase))
|
||||
else:
|
||||
cast[ptr UncheckedArray[char]](alloc(contentSize(newLen)) +! sizeof(NimStrPayloadBase))
|
||||
|
||||
@@ -99,10 +104,9 @@ proc prepareAdd(s: var NimStringV3; addLen: int) {.compilerRtl.} =
|
||||
let oldCap = s.p.cap
|
||||
if newLen > oldCap:
|
||||
let newCap = max(newLen, resize(oldCap))
|
||||
s.p = reallocPayload(s.p -% sizeof(NimStrPayloadBase), newCap)
|
||||
s.p = reallocPayload(head(s.p), newCap)
|
||||
s.p.cap = newCap
|
||||
if newLen < newCap:
|
||||
## TODO: be careful with off by one
|
||||
zeroMem(cast[pointer](addr s.p[newLen]), newCap - newLen)
|
||||
|
||||
proc nimAddCharV1(s: var NimStringV3; c: char) {.compilerRtl, inl.} =
|
||||
@@ -139,6 +143,7 @@ proc appendString(dest: var NimStringV3; src: NimStringV3) {.compilerproc, inlin
|
||||
|
||||
proc appendChar(dest: var NimStringV3; c: char) {.compilerproc, inline.} =
|
||||
dest.p[dest.len] = c
|
||||
incRawLen(dest)
|
||||
|
||||
proc rawNewString(space: int): NimStringV3 {.compilerproc.} =
|
||||
# this is also 'system.newStringOfCap'.
|
||||
@@ -169,15 +174,13 @@ proc setLengthStrV2(s: var NimStringV3, newLen: int) {.compilerRtl.} =
|
||||
copyMem(unsafeAddr s.p[0], unsafeAddr oldP[0], min(s.len, newLen))
|
||||
if newLen > s.len:
|
||||
zeroMem(cast[pointer](addr s.p[s.len]), newLen - s.len)
|
||||
# else:
|
||||
# s.p.data[newLen] = '\0'
|
||||
else:
|
||||
zeroMem(cast[pointer](addr s.p[0]), newLen)
|
||||
elif newLen > s.len:
|
||||
let oldCap = s.p.cap
|
||||
if newLen > oldCap:
|
||||
let newCap = max(newLen, resize(oldCap))
|
||||
s.p = reallocPayload0(s.p -% sizeof(NimStrPayloadBase), oldCap, newCap)
|
||||
s.p = reallocPayload0(head(s.p), oldCap, newCap)
|
||||
s.p.cap = newCap
|
||||
|
||||
s.rawlen = toRawLen(newLen)
|
||||
|
||||
Reference in New Issue
Block a user