summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md8
-rw-r--r--lib/std/strbasics.nim4
-rw-r--r--lib/system.nim6
-rw-r--r--lib/system/strs_v2.nim7
-rw-r--r--tests/arc/t17173.nim10
5 files changed, 33 insertions, 2 deletions
diff --git a/changelog.md b/changelog.md
index aff858818..a21b23b5d 100644
--- a/changelog.md
+++ b/changelog.md
@@ -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
@@ -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])`.
 
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)[])
diff --git a/tests/arc/t17173.nim b/tests/arc/t17173.nim
new file mode 100644
index 000000000..5d868d9d4
--- /dev/null
+++ b/tests/arc/t17173.nim
@@ -0,0 +1,10 @@
+discard """
+  matrix: "--gc:refc; --gc:arc; --newruntime"
+"""
+
+import std/strbasics
+
+
+var a = "  vhellov   "
+strip(a)
+doAssert a == "vhellov"