* fixes #17173

* add testcase (#17214)

* Apply suggestions from code review

* fix for newruntime

* Apply suggestions from code review

* Update lib/system.nim

* Update lib/system.nim

* Update lib/system.nim

Co-authored-by: Danil Yarantsev <tiberiumk12@gmail.com>

Co-authored-by: flywind <xzsflywind@gmail.com>
Co-authored-by: Danil Yarantsev <tiberiumk12@gmail.com>
This commit is contained in:
Andreas Rumpf 2021-03-01 20:58:12 +01:00 • committed by GitHub
commit bb0c19f42c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 2 deletions

View file

@ -130,7 +130,7 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior.
- Deprecated `any`. See https://github.com/nim-lang/RFCs/issues/281 - Deprecated `any`. See https://github.com/nim-lang/RFCs/issues/281
- Added `std/sysrand` module to get random numbers from a secure source - Added `std/sysrand` module to get random numbers from a secure source
provided by the operating system. provided by the operating system.
- Added optional `options` argument to `copyFile`, `copyFileToDir`, and - Added optional `options` argument to `copyFile`, `copyFileToDir`, and
@ -173,6 +173,12 @@ provided by the operating system.
dumping (on select signals) and notifying the parent process about the cause dumping (on select signals) and notifying the parent process about the cause
of termination. of termination.
- Added `system.prepareStrMutation` for better support of low
level `moveMem`, `copyMem` operations for Orc's copy-on-write string
implementation.
- `hashes.hash` now supports `object`, but can be overloaded.
- Added `std/strbasics` for high performance string operations. - Added `std/strbasics` for high performance string operations.
Added `strip`, `setSlice`, `add(a: var string, b: openArray[char])`. Added `strip`, `setSlice`, `add(a: var string, b: openArray[char])`.

View file

@ -80,11 +80,13 @@ func setSlice*(s: var string, slice: Slice[int]) =
when not declared(moveMem): when not declared(moveMem):
impl() impl()
else: else:
when defined(nimSeqsV2):
prepareStrMutation(s)
moveMem(addr s[0], addr s[first], last - first + 1) moveMem(addr s[0], addr s[first], last - first + 1)
s.setLen(last - first + 1) s.setLen(last - first + 1)
func strip*(a: var string, leading = true, trailing = true, chars: set[char] = whitespaces) {.inline.} = func strip*(a: var string, leading = true, trailing = true, chars: set[char] = whitespaces) {.inline.} =
## Inplace version of `strip`. Strips leading or ## Inplace version of `strip`. Strips leading or
## trailing `chars` (default: whitespace characters). ## trailing `chars` (default: whitespace characters).
## ##
## If `leading` is true (default), leading `chars` are stripped. ## If `leading` is true (default), leading `chars` are stripped.

View file

@ -3127,3 +3127,9 @@ export io
when not defined(createNimHcr) and not defined(nimscript): when not defined(createNimHcr) and not defined(nimscript):
include nimhcr include nimhcr
when notJSnotNims and not defined(nimSeqsV2):
proc prepareStrMutation*(s: var string) {.inline.} =
## String literals (e.g. "abc", etc) in the ARC/ORC mode are "copy on write",
## therefore you should call `prepareStrMutation` before modifying the strings.
discard

View file

@ -168,3 +168,10 @@ proc nimPrepareStrMutationImpl(s: var NimStringV2) =
proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl, inline.} = proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl, inline.} =
if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag: if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag:
nimPrepareStrMutationImpl(s) nimPrepareStrMutationImpl(s)
proc prepareStrMutation*(s: var string) {.inline.} =
# string literals are "copy on write", so you need to call
# `prepareStrMutation` before modifying the strings.
{.cast(noSideEffect).}:
let s = unsafeAddr s
nimPrepareStrMutationV2(cast[ptr NimStringV2](s)[])

10
tests/arc/t17173.nim Normal file
View file

@ -0,0 +1,10 @@
discard """
matrix: "--gc:refc; --gc:arc; --newruntime"
"""
import std/strbasics
var a = " vhellov "
strip(a)
doAssert a == "vhellov"