summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorYuriy Glukhov <yglukhov@users.noreply.github.com>2018-07-13 18:41:59 +0300
committerAndreas Rumpf <rumpf_a@web.de>2018-07-13 17:41:59 +0200
commitdfe3f160227dadd5d93bd6c697106e71899eccce (patch)
treead8612cd40f89250bba67a2a3b59f165159cd633 /lib/system
parent54a85b4ff56393e7279f244fe8557ebb36f864ee (diff)
downloadNim-dfe3f160227dadd5d93bd6c697106e71899eccce.tar.gz
Don't depend on string.h in codegen (#8299)
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/alloc.nim4
-rw-r--r--lib/system/ansi_c.nim2
-rw-r--r--lib/system/memory.nim47
-rw-r--r--lib/system/sysio.nim2
-rw-r--r--lib/system/sysstr.nim2
5 files changed, 53 insertions, 4 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 6aef4f411..95becde22 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -830,7 +830,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
     c.freeList = f
     when overwriteFree:
       # set to 0xff to check for usage after free bugs:
-      c_memset(cast[pointer](cast[int](p) +% sizeof(FreeCell)), -1'i32,
+      nimSetMem(cast[pointer](cast[int](p) +% sizeof(FreeCell)), -1'i32,
                s -% sizeof(FreeCell))
     # check if it is not in the freeSmallChunks[s] list:
     if c.free < s:
@@ -847,7 +847,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
                s == 0, "rawDealloc 2")
   else:
     # set to 0xff to check for usage after free bugs:
-    when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead())
+    when overwriteFree: nimSetMem(p, -1'i32, c.size -% bigChunkOverhead())
     # free big chunk
     var c = cast[PBigChunk](c)
     dec a.occ, c.size
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 52cb15e39..4d21f8747 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -25,6 +25,8 @@ proc c_memset(p: pointer, value: cint, size: csize): pointer {.
   importc: "memset", header: "<string.h>", discardable.}
 proc c_strcmp(a, b: cstring): cint {.
   importc: "strcmp", header: "<string.h>", noSideEffect.}
+proc c_strlen(a: cstring): csize {.
+  importc: "strlen", header: "<string.h>", noSideEffect.}
 
 when defined(linux) and defined(amd64):
   type
diff --git a/lib/system/memory.nim b/lib/system/memory.nim
new file mode 100644
index 000000000..f86fd4696
--- /dev/null
+++ b/lib/system/memory.nim
@@ -0,0 +1,47 @@
+const useLibC = not defined(nimNoLibc)
+
+proc nimCopyMem(dest, source: pointer, size: Natural) {.compilerproc, inline.} =
+  when useLibC:
+    c_memcpy(dest, source, size)
+  else:
+    let d = cast[ptr UncheckedArray[byte]](dest)
+    let s = cast[ptr UncheckedArray[byte]](source)
+    var i = 0
+    while i < size:
+      d[i] = s[i]
+      inc i
+
+proc nimSetMem(a: pointer, v: cint, size: Natural) {.inline.} =
+  when useLibC:
+    c_memset(a, v, size)
+  else:
+    let a = cast[ptr UncheckedArray[byte]](a)
+    var i = 0
+    let v = cast[byte](v)
+    while i < size:
+      a[i] = v
+      inc i
+
+proc nimZeroMem(p: pointer, size: Natural) {.compilerproc, inline.} =
+  nimSetMem(p, 0, size)
+
+proc nimCmpMem(a, b: pointer, size: Natural): cint {.compilerproc, inline.} =
+  when useLibC:
+    c_memcmp(a, b, size)
+  else:
+    let a = cast[ptr UncheckedArray[byte]](a)
+    let b = cast[ptr UncheckedArray[byte]](b)
+    var i = 0
+    while i < size:
+      let d = a[i].cint - b[i].cint
+      if d != 0: return d
+      inc i
+
+proc nimCStrLen(a: cstring): csize {.compilerproc, inline.} =
+  when useLibC:
+    c_strlen(a)
+  else:
+    var a = cast[ptr byte](a)
+    while a[] != 0:
+      a = cast[ptr byte](cast[uint](a) + 1)
+      inc result
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index f3a576be0..2ece56916 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -154,7 +154,7 @@ proc readLine(f: File, line: var TaintedString): bool =
   while true:
     # memset to \L so that we can tell how far fgets wrote, even on EOF, where
     # fgets doesn't append an \L
-    c_memset(addr line.string[pos], '\L'.ord, sp)
+    nimSetMem(addr line.string[pos], '\L'.ord, sp)
     var fgetsSuccess = c_fgets(addr line.string[pos], sp, f) != nil
     if not fgetsSuccess: checkErr(f)
     let m = c_memchr(addr line.string[pos], '\L'.ord, sp)
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 90ae91cf5..8e9e18b05 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -32,7 +32,7 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
     let blen = b.len
   let minlen = min(alen, blen)
   if minlen > 0:
-    result = c_memcmp(addr a.data, addr b.data, minlen.csize)
+    result = nimCmpMem(addr a.data, addr b.data, minlen.csize)
     if result == 0:
       result = alen - blen
   else: