This commit is contained in:
araq
2026-03-11 10:11:07 +01:00
parent e20e035f12
commit f5a5874259
7 changed files with 39 additions and 38 deletions

View File

@@ -163,8 +163,7 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
inc(s.lineOffset)
result = min(bufLen, s.s.len - s.rd)
if result > 0:
let (sdata, _) = readRawData(s.s)
copyMem(buf, addr sdata[s.rd], result)
copyMem(buf, readRawData(s.s, s.rd), result)
inc(s.rd, result)
proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
@@ -174,8 +173,7 @@ proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
of llsString:
result = min(bufLen, s.s.len - s.rd)
if result > 0:
let (sdata, _) = readRawData(s.s)
copyMem(buf, addr sdata[s.rd], result)
copyMem(buf, readRawData(s.s, s.rd), result)
inc(s.rd, result)
of llsFile:
result = readBuffer(s.f, buf, bufLen)

View File

@@ -1226,8 +1226,7 @@ else: # after 1.3 or JS not defined
jsOrVmBlock:
buffer[slice.a..<slice.a+result] = s.data[s.pos..<s.pos+result]
do:
let (srcData, _) = readRawData(s.data)
copyMem(beginStore(buffer, result, slice.a), addr srcData[s.pos], result)
copyMem(beginStore(buffer, result, slice.a), readRawData(s.data, s.pos), result)
endStore(buffer)
inc(s.pos, result)
else:
@@ -1244,8 +1243,7 @@ else: # after 1.3 or JS not defined
raise newException(Defect, "could not read string stream, " &
"did you use a non-string buffer pointer?", getCurrentException())
elif not defined(nimscript):
let (srcData, _) = readRawData(s.data)
copyMem(buffer, addr srcData[s.pos], result)
copyMem(buffer, readRawData(s.data, s.pos), result)
inc(s.pos, result)
else:
result = 0
@@ -1261,8 +1259,7 @@ else: # after 1.3 or JS not defined
raise newException(Defect, "could not peek string stream, " &
"did you use a non-string buffer pointer?", getCurrentException())
elif not defined(nimscript):
let (srcData, _) = readRawData(s.data)
copyMem(buffer, addr srcData[s.pos], result)
copyMem(buffer, readRawData(s.data, s.pos), result)
else:
result = 0

View File

@@ -1983,7 +1983,7 @@ func find*(s: string, sub: char, start: Natural = 0, last = -1): int {.rtl,
when hasCStringBuiltin:
let length = last-start+1
if length > 0:
let (sdata, _) = readRawData(s)
let sdata = readRawData(s)
let found = c_memchr(addr sdata[start], cint(sub), cast[csize_t](length))
if not found.isNil:
return cast[int](found) -% cast[int](sdata)
@@ -2042,9 +2042,8 @@ func find*(s, sub: string, start: Natural = 0, last = -1): int {.rtl,
when declared(memmem):
let subLen = sub.len
if last < 0 and start < s.len and subLen != 0:
let (sdata, _) = readRawData(s)
let (subdata, _) = readRawData(sub)
let found = memmem(addr sdata[start], csize_t(s.len - start), subdata, csize_t(subLen))
let sdata = readRawData(s)
let found = memmem(addr sdata[start], csize_t(s.len - start), readRawData(sub), csize_t(subLen))
result = if not found.isNil:
cast[int](found) -% cast[int](sdata)
else:

View File

@@ -496,7 +496,7 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
checkErr(f)
break
let (lineData, _) = readRawData(line)
let lineData = readRawData(line)
let m = c_memchr(addr lineData[pos], cint('\L'), cast[csize_t](sp))
if m != nil:
# \l found: Could be our own or the one by fgets, in any case, we're done

View File

@@ -1699,14 +1699,24 @@ when notJSnotNims and defined(nimSeqsV2):
include "system/seqs_v2"
when not (notJSnotNims and defined(nimSeqsV2)):
# Fallback stubs for js/nimscript/non-V2 backends where strs_v2/v3 is not included.
# These are needed so that modules imported by system (e.g. syncio) can reference
# beginStore/endStore/readRawData without a 'when declared(...)' guard.
proc beginStore*(s: var string; ensuredLen: int; start = 0): ptr UncheckedArray[char] {.inline, noSideEffect.} =
result = cast[ptr UncheckedArray[char]](addr s[start])
proc endStore*(s: var string) {.inline, noSideEffect.} = discard
template readRawData*(s: string): (ptr UncheckedArray[char], int) =
(cast[ptr UncheckedArray[char]](nil), s.len)
# Fallback implementations for backends where strs_v2/v3 is not included.
# Needed so modules imported by system (e.g. syncio) can reference these without guards.
when notJSnotNims:
# mm:refc: string = ptr NimStringDesc with data: UncheckedArray[char]
proc beginStore*(s: var string; ensuredLen: int; start = 0): ptr UncheckedArray[char] {.inline, noSideEffect.} =
let ns = cast[NimString](s)
if ns == nil: nil
else: cast[ptr UncheckedArray[char]](addr ns.data[start])
proc endStore*(s: var string) {.inline, noSideEffect.} = discard
template readRawData*(s: string; start = 0): ptr UncheckedArray[char] =
let ns = cast[NimString](s)
if ns == nil: nil
else: cast[ptr UncheckedArray[char]](addr ns.data[start])
else:
# JS/nimscript: callers are guarded by whenNotVmJsNims/when not defined(js)
proc beginStore*(s: var string; ensuredLen: int; start = 0): ptr UncheckedArray[char] {.inline, noSideEffect.} = nil
proc endStore*(s: var string) {.inline, noSideEffect.} = discard
template readRawData*(s: string; start = 0): ptr UncheckedArray[char] = nil
when not defined(js):
template newSeqImpl(T, len) =
@@ -2975,8 +2985,7 @@ proc substr*(s: string; first, last: int): string = # A bug with `magic: Slice`
result = newStringUninit(L)
whenNotVmJsNims():
if L > 0:
let (src, _) = readRawData(s)
copyMem(beginStore(result, L), addr src[first], L)
copyMem(beginStore(result, L), readRawData(s, first), L)
endStore(result)
do:
for i in 0..<L:

View File

@@ -227,10 +227,10 @@ proc endStore*(s: var string) {.inline, noSideEffect.} =
## No-op for non-SSO strings; call after bulk writes via `beginStore`.
discard
template readRawData*(s: string): (ptr UncheckedArray[char], int) =
## Returns `(dataPtr, length)` for read-only raw access to string data.
template readRawData*(s: string; start = 0): ptr UncheckedArray[char] =
## Returns a pointer to `s[start]` for read-only raw access.
## Template ensures no copy of `s`; ptr is valid while `s` is alive.
let p = if s.len == 0: nil else: cast[ptr UncheckedArray[char]](unsafeAddr s[0])
(p, s.len)
let str = cast[ptr NimStringV2](unsafeAddr s)
if str.p == nil: nil else: cast[ptr UncheckedArray[char]](addr str.p.data[start])
{.pop.}

View File

@@ -692,19 +692,17 @@ proc endStore*(s: var string) {.inline, noSideEffect.} =
## Syncs the inline cache after bulk writes via `beginStore`. No-op for short/medium strings.
{.cast(noSideEffect).}: completeStore(cast[ptr SmallString](addr s)[])
proc rawDataImpl(ss: ptr SmallString): (ptr UncheckedArray[char], int) {.inline.} =
proc rawDataImpl(ss: ptr SmallString; start: int): ptr UncheckedArray[char] {.inline, noSideEffect, raises: [].} =
let slen = ssLen(ss[])
let actualLen = if slen > PayloadSize: ss[].more.fullLen else: slen
let p =
if actualLen == 0: nil
elif slen > PayloadSize: cast[ptr UncheckedArray[char]](addr ss[].more.data[0])
else: inlinePtr(ss[])
(p, actualLen)
if actualLen == 0: nil
elif slen > PayloadSize: cast[ptr UncheckedArray[char]](addr ss[].more.data[start])
else: cast[ptr UncheckedArray[char]](cast[uint](inlinePtr(ss[])) + uint(start))
template readRawData*(s: string): (ptr UncheckedArray[char], int) =
## Returns `(dataPtr, length)` for read-only raw access to string data.
template readRawData*(s: string; start = 0): ptr UncheckedArray[char] =
## Returns a pointer to `s[start]` for read-only raw access.
## Template ensures no copy of `s` is made; ptr is valid while `s` is alive.
rawDataImpl(cast[ptr SmallString](unsafeAddr s))
rawDataImpl(cast[ptr SmallString](unsafeAddr s), start)
# These take `string` (tyString) so the codegen uses them directly, bypassing
# strmantle.nim's versions which go through nimStrLen/nimStrAtMutV3 compilerproc calls.