summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-03-01 20:58:12 +0100
committerGitHub <noreply@github.com>2021-03-01 20:58:12 +0100
commitbb0c19f42cee41d5cdccbb8c47fc83669cba5540 (patch)
tree00e9dcb87b8427053143b61d05e10af7d8460cb3 /lib
parentc625ce80cb31d69f1683f299868572bd2caf2c5f (diff)
downloadNim-bb0c19f42cee41d5cdccbb8c47fc83669cba5540.tar.gz
fixes #17173 (#17213)
* 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>
Diffstat (limited to 'lib')
-rw-r--r--lib/std/strbasics.nim4
-rw-r--r--lib/system.nim6
-rw-r--r--lib/system/strs_v2.nim7
3 files changed, 16 insertions, 1 deletions
diff --git a/lib/std/strbasics.nim b/lib/std/strbasics.nim
index 357e56208..0ea5a2817 100644
--- a/lib/std/strbasics.nim
+++ b/lib/std/strbasics.nim
@@ -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.
diff --git a/lib/system.nim b/lib/system.nim
index 4b182905b..6b7549a48 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -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
diff --git a/lib/system/strs_v2.nim b/lib/system/strs_v2.nim
index fe117997b..b20457d51 100644
--- a/lib/system/strs_v2.nim
+++ b/lib/system/strs_v2.nim
@@ -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.} =
+  # 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)[])