mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-26 16:41:39 +00:00
now with newStringUninit for SSO
This commit is contained in:
@@ -1747,16 +1747,21 @@ when not defined(js):
|
||||
else:
|
||||
{.error: "The type T cannot contain managed memory or have destructors".}
|
||||
|
||||
when not defined(nimsso):
|
||||
proc newStringUninit*(len: Natural): string {.noSideEffect.} =
|
||||
## Returns a new string of length `len` but with uninitialized
|
||||
## content. One needs to fill the string character after character
|
||||
## with the index operator `s[i]`.
|
||||
##
|
||||
## This procedure exists only for optimization purposes;
|
||||
## the same effect can be achieved with the `&` operator or with `add`.
|
||||
when nimvm:
|
||||
result = newString(len)
|
||||
when defined(nimsso) and not declared(newStringUninitWasDeclared):
|
||||
proc newStringUninitImpl(len: Natural): string {.noSideEffect, inline.}
|
||||
|
||||
proc newStringUninit*(len: Natural): string {.noSideEffect.} =
|
||||
## Returns a new string of length `len` but with uninitialized
|
||||
## content. One needs to fill the string character after character
|
||||
## with the index operator `s[i]`.
|
||||
##
|
||||
## This procedure exists only for optimization purposes;
|
||||
## the same effect can be achieved with the `&` operator or with `add`.
|
||||
when nimvm:
|
||||
result = newString(len)
|
||||
else:
|
||||
when defined(nimsso):
|
||||
result = newStringUninitImpl(len)
|
||||
else:
|
||||
result = newStringOfCap(len)
|
||||
{.cast(noSideEffect).}:
|
||||
@@ -1769,9 +1774,6 @@ when not defined(js):
|
||||
let s = cast[NimString](result)
|
||||
s.len = len
|
||||
s.data[len] = '\0'
|
||||
else:
|
||||
proc newStringUninit*(len: Natural): string {.
|
||||
magic: "NewString", importc: "mnewString", noSideEffect.}
|
||||
|
||||
{.pop.}
|
||||
|
||||
@@ -3176,3 +3178,6 @@ when hostOS == "standalone":
|
||||
# ssymbols being duplicated.
|
||||
proc nimPanic(s: string) {.exportc, noreturn.} = panic(s)
|
||||
proc nimRawoutput(s: string) {.exportc.} = rawoutput(s)
|
||||
|
||||
when not declared(newStringUninitWasDeclared):
|
||||
proc newStringUninitImpl(len: Natural): string {.noSideEffect, inline.} = discard
|
||||
|
||||
@@ -509,6 +509,33 @@ proc nimStrData(s: var SmallString): ptr UncheckedArray[char] {.compilerproc, in
|
||||
if slen > PayloadSize: cast[ptr UncheckedArray[char]](addr s.more.data[0])
|
||||
else: cast[ptr UncheckedArray[char]](addr s.payload[0])
|
||||
|
||||
const
|
||||
newStringUninitWasDeclared = true
|
||||
|
||||
proc newStringUninitImpl(len: Natural): string {.noSideEffect, inline.} =
|
||||
## Returns a new string of length `len` but with uninitialized content.
|
||||
## One needs to fill the string character after character
|
||||
## with the index operator `s[i]`.
|
||||
##
|
||||
## This procedure exists only for optimization purposes;
|
||||
## the same effect can be achieved with the `&` operator or with `add`.
|
||||
when nimvm:
|
||||
result = newString(len)
|
||||
else:
|
||||
result = newStringOfCap(len) # rawNewString: alloc (not alloc0) for long strings
|
||||
{.cast(noSideEffect).}:
|
||||
if len > 0:
|
||||
let s = cast[ptr SmallString](addr result)
|
||||
if len <= PayloadSize:
|
||||
s.slen = byte(len)
|
||||
# Null-terminate; bytes [0..len-1] left uninitialized for caller to fill.
|
||||
cast[ptr UncheckedArray[char]](addr s.payload[0])[len] = '\0'
|
||||
else:
|
||||
# rawNewString allocated with alloc (not alloc0), so data[0..len-1] is
|
||||
# intentionally uninitialized. Caller fills it and calls completeStore.
|
||||
s.more.fullLen = len
|
||||
s.more.data[len] = '\0'
|
||||
|
||||
proc completeStore(s: var SmallString) {.compilerproc, inline.} =
|
||||
## Must be called after bulk data has been written directly into the string buffer
|
||||
## via a raw pointer obtained from `nimStrData`/`nimStrAtMutV3` (e.g. `readBuffer`,
|
||||
|
||||
Reference in New Issue
Block a user