Don't depend on string.h in codegen (#8299)

This commit is contained in:
Yuriy Glukhov
2018-07-13 18:41:59 +03:00
committed by Andreas Rumpf
parent 54a85b4ff5
commit dfe3f16022
9 changed files with 87 additions and 54 deletions

View File

@@ -322,8 +322,7 @@ type MemSlice* = object ## represent slice of a MemFile for iteration over deli
proc `==`*(x, y: MemSlice): bool =
## Compare a pair of MemSlice for strict equality.
proc memcmp(a, b: pointer, n:int):int {.importc: "memcmp",header: "string.h".}
result = (x.size == y.size and memcmp(x.data, y.data, x.size) == 0)
result = (x.size == y.size and equalMem(x.data, y.data, x.size))
proc `$`*(ms: MemSlice): string {.inline.} =
## Return a Nim string built from a MemSlice.

View File

@@ -2903,6 +2903,22 @@ when not defined(JS): #and not defined(nimscript):
## useful for low-level file access
include "system/ansi_c"
include "system/memory"
proc zeroMem(p: pointer, size: Natural) =
nimZeroMem(p, size)
when declared(memTrackerOp):
memTrackerOp("zeroMem", p, size)
proc copyMem(dest, source: pointer, size: Natural) =
nimCopyMem(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("copyMem", dest, size)
proc moveMem(dest, source: pointer, size: Natural) =
c_memmove(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("moveMem", dest, size)
proc equalMem(a, b: pointer, size: Natural): bool =
nimCmpMem(a, b, size) == 0
proc cmp(x, y: string): int =
when nimvm:
@@ -2911,7 +2927,7 @@ when not defined(JS): #and not defined(nimscript):
else: result = 0
else:
let minlen = min(x.len, y.len)
result = int(c_memcmp(x.cstring, y.cstring, minlen.csize))
result = int(nimCmpMem(x.cstring, y.cstring, minlen.csize))
if result == 0:
result = x.len - y.len
@@ -3200,22 +3216,6 @@ when not defined(JS): #and not defined(nimscript):
when defined(memtracker):
include "system/memtracker"
when not defined(nimscript):
proc zeroMem(p: pointer, size: Natural) =
c_memset(p, 0, size)
when declared(memTrackerOp):
memTrackerOp("zeroMem", p, size)
proc copyMem(dest, source: pointer, size: Natural) =
c_memcpy(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("copyMem", dest, size)
proc moveMem(dest, source: pointer, size: Natural) =
c_memmove(dest, source, size)
when declared(memTrackerOp):
memTrackerOp("moveMem", dest, size)
proc equalMem(a, b: pointer, size: Natural): bool =
c_memcmp(a, b, size) == 0
when hostOS == "standalone":
include "system/embedded"
else:

View File

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

View File

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

47
lib/system/memory.nim Normal file
View File

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

View File

@@ -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)

View File

@@ -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: