diff --git a/compiler/llstream.nim b/compiler/llstream.nim index 77cb94eb7e..98fa1efdfe 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -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) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 1c31ca0752..a1fffa5d95 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -1226,8 +1226,7 @@ else: # after 1.3 or JS not defined jsOrVmBlock: buffer[slice.a.. 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: diff --git a/lib/std/syncio.nim b/lib/std/syncio.nim index 153b79c660..70a0c711cb 100644 --- a/lib/std/syncio.nim +++ b/lib/std/syncio.nim @@ -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 diff --git a/lib/system.nim b/lib/system.nim index 37fc344929..0fc7603490 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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.. 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.