summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/includes/osenv.nim5
-rw-r--r--lib/system/widestrs.nim57
-rw-r--r--tests/concepts/t3330.nim12
-rw-r--r--tests/destructor/tnewruntime_misc.nim (renamed from tests/destructor/tsimpletable.nim)10
4 files changed, 70 insertions, 14 deletions
diff --git a/lib/pure/includes/osenv.nim b/lib/pure/includes/osenv.nim
index 193efd4d4..1ddc51f8f 100644
--- a/lib/pure/includes/osenv.nim
+++ b/lib/pure/includes/osenv.nim
@@ -19,6 +19,11 @@ var
   envComputed {.threadvar.}: bool
   environment {.threadvar.}: seq[string]
 
+when defined(nimV2):
+  proc unpairedEnvAllocs*(): int =
+    result = environment.len
+    if result > 0: inc result
+
 when defined(windows) and not defined(nimscript):
   # because we support Windows GUI applications, things get really
   # messy here...
diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim
index 31181e027..cf5e728d7 100644
--- a/lib/system/widestrs.nim
+++ b/lib/system/widestrs.nim
@@ -15,7 +15,52 @@
 
 type
   Utf16Char* = distinct int16
-  WideCString* = ref UncheckedArray[Utf16Char]
+
+when defined(nimv2):
+
+  import core / allocators
+
+  type
+    WideCString* = ptr UncheckedArray[Utf16Char]
+
+    WideCStringObj* = object
+      bytes: int
+      data: WideCString
+
+  proc `=destroy`(a: var WideCStringObj) =
+    if a.data != nil:
+      let alor = getLocalAllocator()
+      alor.dealloc(alor, a.data, a.bytes)
+      a.data = nil
+
+  proc `=`(a: var WideCStringObj; b: WideCStringObj) {.error.}
+
+  proc `=sink`(a: var WideCStringObj; b: WideCStringObj) =
+    a.bytes = b.bytes
+    a.data = b.data
+
+  proc createWide(a: var WideCStringObj; bytes: int) =
+    a.bytes = bytes
+    let alor = getLocalAllocator()
+    a.data = cast[typeof(a.data)](alor.alloc(alor, bytes))
+
+  template `[]`(a: WideCStringObj; idx: int): Utf16Char = a.data[idx]
+  template `[]=`(a: WideCStringObj; idx: int; val: Utf16Char) = a.data[idx] = val
+
+  template nullWide(): untyped = WideCStringObj(bytes: 0, data: nil)
+
+  converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
+    result = x.data
+
+else:
+  template nullWide(): untyped = nil
+
+  type
+    WideCString* = ref UncheckedArray[Utf16Char]
+    WideCStringObj* = WideCString
+
+  template createWide(a; L) =
+    unsafeNew(a, L * 4 + 2)
 
 proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
 
@@ -95,8 +140,8 @@ iterator runes(s: cstring, L: int): int =
     fastRuneAt(s, i, L, result, true)
     yield result
 
-proc newWideCString*(source: cstring, L: int): WideCString =
-  unsafeNew(result, L * 4 + 2)
+proc newWideCString*(source: cstring, L: int): WideCStringObj =
+  createWide(result, L * 4 + 2)
   #result = cast[wideCString](alloc(L * 4 + 2))
   var d = 0
   for ch in runes(source, L):
@@ -116,12 +161,12 @@ proc newWideCString*(source: cstring, L: int): WideCString =
     inc d
   result[d] = Utf16Char(0)
 
-proc newWideCString*(s: cstring): WideCString =
-  if s.isNil: return nil
+proc newWideCString*(s: cstring): WideCStringObj =
+  if s.isNil: return nullWide
 
   result = newWideCString(s, s.len)
 
-proc newWideCString*(s: string): WideCString =
+proc newWideCString*(s: string): WideCStringObj =
   result = newWideCString(s, s.len)
 
 proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim
index 6bf52f3aa..ed1590e16 100644
--- a/tests/concepts/t3330.nim
+++ b/tests/concepts/t3330.nim
@@ -13,21 +13,21 @@ proc add[T](x: var seq[T]; y: openArray[T])
   first type mismatch at position: 1
   required type for x: var seq[T]
   but expression 'k' is of type: Alias
-proc add(result: var string; x: float)
+proc add[T](x: var seq[T]; y: T)
   first type mismatch at position: 1
-  required type for result: var string
+  required type for x: var seq[T]
   but expression 'k' is of type: Alias
-proc add(x: var string; y: string)
+proc add(result: var string; x: float)
   first type mismatch at position: 1
-  required type for x: var string
+  required type for result: var string
   but expression 'k' is of type: Alias
 proc add(x: var string; y: cstring)
   first type mismatch at position: 1
   required type for x: var string
   but expression 'k' is of type: Alias
-proc add[T](x: var seq[T]; y: T)
+proc add(x: var string; y: string)
   first type mismatch at position: 1
-  required type for x: var seq[T]
+  required type for x: var string
   but expression 'k' is of type: Alias
 proc add(result: var string; x: int64)
   first type mismatch at position: 1
diff --git a/tests/destructor/tsimpletable.nim b/tests/destructor/tnewruntime_misc.nim
index 34a4ac063..029a2a78d 100644
--- a/tests/destructor/tsimpletable.nim
+++ b/tests/destructor/tnewruntime_misc.nim
@@ -1,7 +1,8 @@
 discard """
   cmd: '''nim cpp --newruntime $file'''
   output: '''(field: "value")
-3 3  new: 0'''
+Indeed
+0  new: 0'''
 """
 
 import core / allocators
@@ -13,10 +14,15 @@ type
   Node = ref object
     field: string
 
+# bug #11807
+import os
+putEnv("HEAPTRASHING", "Indeed")
+
 proc main =
   var w = newTable[string, owned Node]()
   w["key"] = Node(field: "value")
   echo w["key"][]
+  echo getEnv("HEAPTRASHING")
 
 main()
 
@@ -41,4 +47,4 @@ type
 var t: MyType
 
 let (a, d) = allocCounters()
-discard cprintf("%ld %ld  new: %ld\n", a, d, allocs)
+discard cprintf("%ld  new: %ld\n", a - unpairedEnvAllocs() - d, allocs)