respect -d:useMalloc everywhere; turn ansi_c and memory into proper Nim modules

This commit is contained in:
Araq 2019-04-08 17:09:27 +02:00
commit 6efa7ecf18
4 changed files with 83 additions and 66 deletions

View file

@ -27,18 +27,33 @@ var
sharedAllocator: Allocator sharedAllocator: Allocator
allocatorStorage {.threadvar.}: AllocatorObj allocatorStorage {.threadvar.}: AllocatorObj
when defined(useMalloc) and not defined(nimscript):
import "system/ansi_c"
import "system/memory"
proc getLocalAllocator*(): Allocator = proc getLocalAllocator*(): Allocator =
result = localAllocator result = localAllocator
if result == nil: if result == nil:
result = addr allocatorStorage result = addr allocatorStorage
result.alloc = proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [].} = result.alloc = proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [].} =
result = system.alloc(size) when defined(useMalloc) and not defined(nimscript):
result = c_malloc(size)
# XXX do we need this?
nimZeroMem(result, size)
else:
result = system.alloc(size)
inc a.allocCount inc a.allocCount
result.dealloc = proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [].} = result.dealloc = proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [].} =
system.dealloc(p) when defined(useMalloc) and not defined(nimscript):
c_free(p)
else:
system.dealloc(p)
inc a.deallocCount inc a.deallocCount
result.realloc = proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [].} = result.realloc = proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [].} =
result = system.realloc(p, newSize) when defined(useMalloc) and not defined(nimscript):
result = c_realloc(p, newSize)
else:
result = system.realloc(p, newSize)
result.deallocAll = nil result.deallocAll = nil
result.flags = {ThreadLocal} result.flags = {ThreadLocal}
result.name = "nim_local" result.name = "nim_local"

View file

@ -2969,7 +2969,8 @@ proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.
discard discard
when not defined(js) and not defined(nimscript): when not defined(js) and not defined(nimscript):
include "system/ansi_c" import "system/ansi_c"
import "system/memory"
when not defined(js): when not defined(js):
{.push stackTrace:off.} {.push stackTrace:off.}
@ -3468,8 +3469,6 @@ when not defined(JS): #and not defined(nimscript):
{.pop.} {.pop.}
when not defined(nimscript): when not defined(nimscript):
include "system/memory"
proc zeroMem(p: pointer, size: Natural) = proc zeroMem(p: pointer, size: Natural) =
nimZeroMem(p, size) nimZeroMem(p, size)
when declared(memTrackerOp): when declared(memTrackerOp):

View file

@ -7,108 +7,108 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
# This include file contains headers of Ansi C procs # This module contains headers of Ansi C procs
# and definitions of Ansi C types in Nim syntax # and definitions of Ansi C types in Nim syntax
# All symbols are prefixed with 'c_' to avoid ambiguities # All symbols are prefixed with 'c_' to avoid ambiguities
{.push hints:off, stack_trace: off, profiler: off.} {.push hints:off, stack_trace: off, profiler: off.}
proc c_memchr(s: pointer, c: cint, n: csize): pointer {. proc c_memchr*(s: pointer, c: cint, n: csize): pointer {.
importc: "memchr", header: "<string.h>".} importc: "memchr", header: "<string.h>".}
proc c_memcmp(a, b: pointer, size: csize): cint {. proc c_memcmp*(a, b: pointer, size: csize): cint {.
importc: "memcmp", header: "<string.h>", noSideEffect.} importc: "memcmp", header: "<string.h>", noSideEffect.}
proc c_memcpy(a, b: pointer, size: csize): pointer {. proc c_memcpy*(a, b: pointer, size: csize): pointer {.
importc: "memcpy", header: "<string.h>", discardable.} importc: "memcpy", header: "<string.h>", discardable.}
proc c_memmove(a, b: pointer, size: csize): pointer {. proc c_memmove*(a, b: pointer, size: csize): pointer {.
importc: "memmove", header: "<string.h>",discardable.} importc: "memmove", header: "<string.h>",discardable.}
proc c_memset(p: pointer, value: cint, size: csize): pointer {. proc c_memset*(p: pointer, value: cint, size: csize): pointer {.
importc: "memset", header: "<string.h>", discardable.} importc: "memset", header: "<string.h>", discardable.}
proc c_strcmp(a, b: cstring): cint {. proc c_strcmp*(a, b: cstring): cint {.
importc: "strcmp", header: "<string.h>", noSideEffect.} importc: "strcmp", header: "<string.h>", noSideEffect.}
proc c_strlen(a: cstring): csize {. proc c_strlen*(a: cstring): csize {.
importc: "strlen", header: "<string.h>", noSideEffect.} importc: "strlen", header: "<string.h>", noSideEffect.}
proc c_abort() {. proc c_abort*() {.
importc: "abort", header: "<stdlib.h>", noSideEffect.} importc: "abort", header: "<stdlib.h>", noSideEffect.}
when defined(linux) and defined(amd64): when defined(linux) and defined(amd64):
type type
C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>", bycopy.} = object C_JmpBuf* {.importc: "jmp_buf", header: "<setjmp.h>", bycopy.} = object
abi: array[200 div sizeof(clong), clong] abi: array[200 div sizeof(clong), clong]
else: else:
type type
C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object C_JmpBuf* {.importc: "jmp_buf", header: "<setjmp.h>".} = object
when defined(windows): when defined(windows):
const const
SIGABRT = cint(22) SIGABRT* = cint(22)
SIGFPE = cint(8) SIGFPE* = cint(8)
SIGILL = cint(4) SIGILL* = cint(4)
SIGINT = cint(2) SIGINT* = cint(2)
SIGSEGV = cint(11) SIGSEGV* = cint(11)
SIGTERM = cint(15) SIGTERM = cint(15)
elif defined(macosx) or defined(linux) or defined(freebsd) or elif defined(macosx) or defined(linux) or defined(freebsd) or
defined(openbsd) or defined(netbsd) or defined(solaris) or defined(openbsd) or defined(netbsd) or defined(solaris) or
defined(dragonfly) or defined(nintendoswitch) or defined(genode) or defined(dragonfly) or defined(nintendoswitch) or defined(genode) or
defined(aix) or hostOS == "standalone": defined(aix) or hostOS == "standalone":
const const
SIGABRT = cint(6) SIGABRT* = cint(6)
SIGFPE = cint(8) SIGFPE* = cint(8)
SIGILL = cint(4) SIGILL* = cint(4)
SIGINT = cint(2) SIGINT* = cint(2)
SIGSEGV = cint(11) SIGSEGV* = cint(11)
SIGTERM = cint(15) SIGTERM* = cint(15)
SIGPIPE = cint(13) SIGPIPE* = cint(13)
elif defined(haiku): elif defined(haiku):
const const
SIGABRT = cint(6) SIGABRT* = cint(6)
SIGFPE = cint(8) SIGFPE* = cint(8)
SIGILL = cint(4) SIGILL* = cint(4)
SIGINT = cint(2) SIGINT* = cint(2)
SIGSEGV = cint(11) SIGSEGV* = cint(11)
SIGTERM = cint(15) SIGTERM* = cint(15)
SIGPIPE = cint(7) SIGPIPE* = cint(7)
else: else:
when NoFakeVars: when NoFakeVars:
{.error: "SIGABRT not ported to your platform".} {.error: "SIGABRT not ported to your platform".}
else: else:
var var
SIGINT {.importc: "SIGINT", nodecl.}: cint SIGINT* {.importc: "SIGINT", nodecl.}: cint
SIGSEGV {.importc: "SIGSEGV", nodecl.}: cint SIGSEGV* {.importc: "SIGSEGV", nodecl.}: cint
SIGABRT {.importc: "SIGABRT", nodecl.}: cint SIGABRT* {.importc: "SIGABRT", nodecl.}: cint
SIGFPE {.importc: "SIGFPE", nodecl.}: cint SIGFPE* {.importc: "SIGFPE", nodecl.}: cint
SIGILL {.importc: "SIGILL", nodecl.}: cint SIGILL* {.importc: "SIGILL", nodecl.}: cint
when defined(macosx) or defined(linux): when defined(macosx) or defined(linux):
var SIGPIPE {.importc: "SIGPIPE", nodecl.}: cint var SIGPIPE* {.importc: "SIGPIPE", nodecl.}: cint
when defined(macosx): when defined(macosx):
const SIGBUS = cint(10) const SIGBUS* = cint(10)
elif defined(haiku): elif defined(haiku):
const SIGBUS = cint(30) const SIGBUS* = cint(30)
else: else:
template SIGBUS: untyped = SIGSEGV template SIGBUS*: untyped = SIGSEGV
when defined(nimSigSetjmp) and not defined(nimStdSetjmp): when defined(nimSigSetjmp) and not defined(nimStdSetjmp):
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {. proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "siglongjmp".} header: "<setjmp.h>", importc: "siglongjmp".}
template c_setjmp(jmpb: C_JmpBuf): cint = template c_setjmp*(jmpb: C_JmpBuf): cint =
proc c_sigsetjmp(jmpb: C_JmpBuf, savemask: cint): cint {. proc c_sigsetjmp(jmpb: C_JmpBuf, savemask: cint): cint {.
header: "<setjmp.h>", importc: "sigsetjmp".} header: "<setjmp.h>", importc: "sigsetjmp".}
c_sigsetjmp(jmpb, 0) c_sigsetjmp(jmpb, 0)
elif defined(nimRawSetjmp) and not defined(nimStdSetjmp): elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {. proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "_longjmp".} header: "<setjmp.h>", importc: "_longjmp".}
proc c_setjmp(jmpb: C_JmpBuf): cint {. proc c_setjmp*(jmpb: C_JmpBuf): cint {.
header: "<setjmp.h>", importc: "_setjmp".} header: "<setjmp.h>", importc: "_setjmp".}
else: else:
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {. proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "longjmp".} header: "<setjmp.h>", importc: "longjmp".}
proc c_setjmp(jmpb: C_JmpBuf): cint {. proc c_setjmp*(jmpb: C_JmpBuf): cint {.
header: "<setjmp.h>", importc: "setjmp".} header: "<setjmp.h>", importc: "setjmp".}
type c_sighandler_t = proc (a: cint) {.noconv.} type c_sighandler_t = proc (a: cint) {.noconv.}
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}): c_sighandler_t {. proc c_signal*(sign: cint, handler: proc (a: cint) {.noconv.}): c_sighandler_t {.
importc: "signal", header: "<signal.h>", discardable.} importc: "signal", header: "<signal.h>", discardable.}
type type
@ -120,29 +120,29 @@ var
cstderr* {.importc: "stderr", header: "<stdio.h>".}: CFilePtr cstderr* {.importc: "stderr", header: "<stdio.h>".}: CFilePtr
cstdout* {.importc: "stdout", header: "<stdio.h>".}: CFilePtr cstdout* {.importc: "stdout", header: "<stdio.h>".}: CFilePtr
proc c_fprintf(f: CFilePtr, frmt: cstring): cint {. proc c_fprintf*(f: CFilePtr, frmt: cstring): cint {.
importc: "fprintf", header: "<stdio.h>", varargs, discardable.} importc: "fprintf", header: "<stdio.h>", varargs, discardable.}
proc c_printf(frmt: cstring): cint {. proc c_printf*(frmt: cstring): cint {.
importc: "printf", header: "<stdio.h>", varargs, discardable.} importc: "printf", header: "<stdio.h>", varargs, discardable.}
proc c_fputs(c: cstring, f: CFilePtr): cint {. proc c_fputs*(c: cstring, f: CFilePtr): cint {.
importc: "fputs", header: "<stdio.h>", discardable.} importc: "fputs", header: "<stdio.h>", discardable.}
proc c_sprintf(buf, frmt: cstring): cint {. proc c_sprintf*(buf, frmt: cstring): cint {.
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.} importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
# we use it only in a way that cannot lead to security issues # we use it only in a way that cannot lead to security issues
proc c_malloc(size: csize): pointer {. proc c_malloc*(size: csize): pointer {.
importc: "malloc", header: "<stdlib.h>".} importc: "malloc", header: "<stdlib.h>".}
proc c_free(p: pointer) {. proc c_free*(p: pointer) {.
importc: "free", header: "<stdlib.h>".} importc: "free", header: "<stdlib.h>".}
proc c_realloc(p: pointer, newsize: csize): pointer {. proc c_realloc*(p: pointer, newsize: csize): pointer {.
importc: "realloc", header: "<stdlib.h>".} importc: "realloc", header: "<stdlib.h>".}
proc c_fwrite(buf: pointer, size, n: csize, f: CFilePtr): cint {. proc c_fwrite*(buf: pointer, size, n: csize, f: CFilePtr): cint {.
importc: "fwrite", header: "<stdio.h>".} importc: "fwrite", header: "<stdio.h>".}
proc rawWrite(f: CFilePtr, s: cstring) {.compilerproc, nonreloadable, inline.} = proc rawWrite*(f: CFilePtr, s: cstring) {.compilerproc, nonreloadable, inline.} =
# we cannot throw an exception here! # we cannot throw an exception here!
discard c_fwrite(s, 1, s.len, f) discard c_fwrite(s, 1, s.len, f)

View file

@ -1,6 +1,9 @@
const useLibC = not defined(nimNoLibc) const useLibC = not defined(nimNoLibc)
proc nimCopyMem(dest, source: pointer, size: Natural) {.compilerproc, inline.} = when useLibC:
import ansi_c
proc nimCopyMem*(dest, source: pointer, size: Natural) {.compilerproc, inline.} =
when useLibC: when useLibC:
c_memcpy(dest, source, size) c_memcpy(dest, source, size)
else: else:
@ -11,7 +14,7 @@ proc nimCopyMem(dest, source: pointer, size: Natural) {.compilerproc, inline.} =
d[i] = s[i] d[i] = s[i]
inc i inc i
proc nimSetMem(a: pointer, v: cint, size: Natural) {.nonReloadable, inline.} = proc nimSetMem*(a: pointer, v: cint, size: Natural) {.nonReloadable, inline.} =
when useLibC: when useLibC:
c_memset(a, v, size) c_memset(a, v, size)
else: else:
@ -22,10 +25,10 @@ proc nimSetMem(a: pointer, v: cint, size: Natural) {.nonReloadable, inline.} =
a[i] = v a[i] = v
inc i inc i
proc nimZeroMem(p: pointer, size: Natural) {.compilerproc, nonReloadable, inline.} = proc nimZeroMem*(p: pointer, size: Natural) {.compilerproc, nonReloadable, inline.} =
nimSetMem(p, 0, size) nimSetMem(p, 0, size)
proc nimCmpMem(a, b: pointer, size: Natural): cint {.compilerproc, inline.} = proc nimCmpMem*(a, b: pointer, size: Natural): cint {.compilerproc, inline.} =
when useLibC: when useLibC:
c_memcmp(a, b, size) c_memcmp(a, b, size)
else: else:
@ -37,7 +40,7 @@ proc nimCmpMem(a, b: pointer, size: Natural): cint {.compilerproc, inline.} =
if d != 0: return d if d != 0: return d
inc i inc i
proc nimCStrLen(a: cstring): csize {.compilerproc, nonReloadable, inline.} = proc nimCStrLen*(a: cstring): csize {.compilerproc, nonReloadable, inline.} =
when useLibC: when useLibC:
c_strlen(a) c_strlen(a)
else: else: