Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes #17173 #17213

Merged
merged 10 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

- 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.

- Added optional `options` argument to `copyFile`, `copyFileToDir`, and
Expand Down Expand Up @@ -173,6 +173,12 @@ provided by the operating system.
dumping (on select signals) and notifying the parent process about the cause
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 `strip`, `setSlice`, `add(a: var string, b: openArray[char])`.

Expand Down
4 changes: 3 additions & 1 deletion lib/std/strbasics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,13 @@ func setSlice*(s: var string, slice: Slice[int]) =
when not declared(moveMem):
impl()
else:
when defined(nimSeqsV2):
prepareStrMutation(s)
moveMem(addr s[0], addr s[first], last - first + 1)
s.setLen(last - first + 1)

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).
##
## If `leading` is true (default), leading `chars` are stripped.
Expand Down
6 changes: 6 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3127,3 +3127,9 @@ export io

when not defined(createNimHcr) and not defined(nimscript):
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
7 changes: 7 additions & 0 deletions lib/system/strs_v2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,10 @@ proc nimPrepareStrMutationImpl(s: var NimStringV2) =
proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl, inline.} =
if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag:
nimPrepareStrMutationImpl(s)

proc prepareStrMutation*(s: var string) {.inline.} =
ringabout marked this conversation as resolved.
Show resolved Hide resolved
# 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 changes: 10 additions & 0 deletions tests/arc/t17173.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
discard """
matrix: "--gc:refc; --gc:arc; --newruntime"
"""

import std/strbasics


var a = " vhellov "
strip(a)
doAssert a == "vhellov"