introduced 'benign' pragma
This commit is contained in:
parent
2dba3acfa9
commit
a639824e5e
14 changed files with 125 additions and 117 deletions
|
|
@ -41,7 +41,7 @@ proc countDefinedSymbols*(): int =
|
||||||
for key, val in pairs(gSymbols):
|
for key, val in pairs(gSymbols):
|
||||||
if val == "true": inc(result)
|
if val == "true": inc(result)
|
||||||
|
|
||||||
# For ease of bootstrapping, we keep there here and not in the global config
|
# For ease of bootstrapping, we keep them here and not in the global config
|
||||||
# file for now:
|
# file for now:
|
||||||
const
|
const
|
||||||
additionalSymbols = """
|
additionalSymbols = """
|
||||||
|
|
@ -88,6 +88,7 @@ proc initDefines*() =
|
||||||
defineSymbol("nimrequiresnimframe")
|
defineSymbol("nimrequiresnimframe")
|
||||||
defineSymbol("nimparsebiggestfloatmagic")
|
defineSymbol("nimparsebiggestfloatmagic")
|
||||||
defineSymbol("nimalias")
|
defineSymbol("nimalias")
|
||||||
|
defineSymbol("nimlocks")
|
||||||
|
|
||||||
# add platform specific symbols:
|
# add platform specific symbols:
|
||||||
for c in low(CPU)..high(CPU):
|
for c in low(CPU)..high(CPU):
|
||||||
|
|
|
||||||
|
|
@ -458,6 +458,8 @@ proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) =
|
||||||
addTag(tracked, createTag(n))
|
addTag(tracked, createTag(n))
|
||||||
let lockLevel = if op.lockLevel == UnspecifiedLockLevel: UnknownLockLevel
|
let lockLevel = if op.lockLevel == UnspecifiedLockLevel: UnknownLockLevel
|
||||||
else: op.lockLevel
|
else: op.lockLevel
|
||||||
|
#if lockLevel == UnknownLockLevel:
|
||||||
|
# message(n.info, warnUser, "had to assume the worst here")
|
||||||
mergeLockLevels(tracked, n, lockLevel)
|
mergeLockLevels(tracked, n, lockLevel)
|
||||||
|
|
||||||
proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
|
proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
|
||||||
|
|
|
||||||
136
lib/system.nim
136
lib/system.nim
|
|
@ -1318,20 +1318,20 @@ proc substr*(s: string, first, last: int): string {.
|
||||||
## or `limit`:idx: a string's length.
|
## or `limit`:idx: a string's length.
|
||||||
|
|
||||||
when not defined(nimrodVM):
|
when not defined(nimrodVM):
|
||||||
proc zeroMem*(p: pointer, size: int) {.importc, noDecl, gcsafe.}
|
proc zeroMem*(p: pointer, size: int) {.importc, noDecl, benign.}
|
||||||
## overwrites the contents of the memory at ``p`` with the value 0.
|
## overwrites the contents of the memory at ``p`` with the value 0.
|
||||||
## Exactly ``size`` bytes will be overwritten. Like any procedure
|
## Exactly ``size`` bytes will be overwritten. Like any procedure
|
||||||
## dealing with raw memory this is *unsafe*.
|
## dealing with raw memory this is *unsafe*.
|
||||||
|
|
||||||
proc copyMem*(dest, source: pointer, size: int) {.
|
proc copyMem*(dest, source: pointer, size: int) {.
|
||||||
importc: "memcpy", header: "<string.h>", gcsafe.}
|
importc: "memcpy", header: "<string.h>", benign.}
|
||||||
## copies the contents from the memory at ``source`` to the memory
|
## copies the contents from the memory at ``source`` to the memory
|
||||||
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
||||||
## regions may not overlap. Like any procedure dealing with raw
|
## regions may not overlap. Like any procedure dealing with raw
|
||||||
## memory this is *unsafe*.
|
## memory this is *unsafe*.
|
||||||
|
|
||||||
proc moveMem*(dest, source: pointer, size: int) {.
|
proc moveMem*(dest, source: pointer, size: int) {.
|
||||||
importc: "memmove", header: "<string.h>", gcsafe.}
|
importc: "memmove", header: "<string.h>", benign.}
|
||||||
## copies the contents from the memory at ``source`` to the memory
|
## copies the contents from the memory at ``source`` to the memory
|
||||||
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
||||||
## regions may overlap, ``moveMem`` handles this case appropriately
|
## regions may overlap, ``moveMem`` handles this case appropriately
|
||||||
|
|
@ -1346,14 +1346,14 @@ when not defined(nimrodVM):
|
||||||
## *unsafe*.
|
## *unsafe*.
|
||||||
|
|
||||||
when hostOS != "standalone":
|
when hostOS != "standalone":
|
||||||
proc alloc*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.}
|
proc alloc*(size: int): pointer {.noconv, rtl, tags: [], benign.}
|
||||||
## allocates a new memory block with at least ``size`` bytes. The
|
## allocates a new memory block with at least ``size`` bytes. The
|
||||||
## block has to be freed with ``realloc(block, 0)`` or
|
## block has to be freed with ``realloc(block, 0)`` or
|
||||||
## ``dealloc(block)``. The block is not initialized, so reading
|
## ``dealloc(block)``. The block is not initialized, so reading
|
||||||
## from it before writing to it is undefined behaviour!
|
## from it before writing to it is undefined behaviour!
|
||||||
## The allocated memory belongs to its allocating thread!
|
## The allocated memory belongs to its allocating thread!
|
||||||
## Use `allocShared` to allocate from a shared heap.
|
## Use `allocShared` to allocate from a shared heap.
|
||||||
proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} =
|
proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} =
|
||||||
## allocates a new memory block with at least ``T.sizeof * size``
|
## allocates a new memory block with at least ``T.sizeof * size``
|
||||||
## bytes. The block has to be freed with ``resize(block, 0)`` or
|
## bytes. The block has to be freed with ``resize(block, 0)`` or
|
||||||
## ``free(block)``. The block is not initialized, so reading
|
## ``free(block)``. The block is not initialized, so reading
|
||||||
|
|
@ -1361,14 +1361,14 @@ when not defined(nimrodVM):
|
||||||
## The allocated memory belongs to its allocating thread!
|
## The allocated memory belongs to its allocating thread!
|
||||||
## Use `createSharedU` to allocate from a shared heap.
|
## Use `createSharedU` to allocate from a shared heap.
|
||||||
cast[ptr T](alloc(T.sizeof * size))
|
cast[ptr T](alloc(T.sizeof * size))
|
||||||
proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.}
|
proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], benign.}
|
||||||
## allocates a new memory block with at least ``size`` bytes. The
|
## allocates a new memory block with at least ``size`` bytes. The
|
||||||
## block has to be freed with ``realloc(block, 0)`` or
|
## block has to be freed with ``realloc(block, 0)`` or
|
||||||
## ``dealloc(block)``. The block is initialized with all bytes
|
## ``dealloc(block)``. The block is initialized with all bytes
|
||||||
## containing zero, so it is somewhat safer than ``alloc``.
|
## containing zero, so it is somewhat safer than ``alloc``.
|
||||||
## The allocated memory belongs to its allocating thread!
|
## The allocated memory belongs to its allocating thread!
|
||||||
## Use `allocShared0` to allocate from a shared heap.
|
## Use `allocShared0` to allocate from a shared heap.
|
||||||
proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} =
|
proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} =
|
||||||
## allocates a new memory block with at least ``T.sizeof * size``
|
## allocates a new memory block with at least ``T.sizeof * size``
|
||||||
## bytes. The block has to be freed with ``resize(block, 0)`` or
|
## bytes. The block has to be freed with ``resize(block, 0)`` or
|
||||||
## ``free(block)``. The block is initialized with all bytes
|
## ``free(block)``. The block is initialized with all bytes
|
||||||
|
|
@ -1377,7 +1377,7 @@ when not defined(nimrodVM):
|
||||||
## Use `createShared` to allocate from a shared heap.
|
## Use `createShared` to allocate from a shared heap.
|
||||||
cast[ptr T](alloc0(T.sizeof * size))
|
cast[ptr T](alloc0(T.sizeof * size))
|
||||||
proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [],
|
proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [],
|
||||||
gcsafe.}
|
benign.}
|
||||||
## grows or shrinks a given memory block. If p is **nil** then a new
|
## grows or shrinks a given memory block. If p is **nil** then a new
|
||||||
## memory block is returned. In either way the block has at least
|
## memory block is returned. In either way the block has at least
|
||||||
## ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
|
## ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
|
||||||
|
|
@ -1385,7 +1385,7 @@ when not defined(nimrodVM):
|
||||||
## be freed with ``dealloc``.
|
## be freed with ``dealloc``.
|
||||||
## The allocated memory belongs to its allocating thread!
|
## The allocated memory belongs to its allocating thread!
|
||||||
## Use `reallocShared` to reallocate from a shared heap.
|
## Use `reallocShared` to reallocate from a shared heap.
|
||||||
proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, gcsafe.} =
|
proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, benign.} =
|
||||||
## grows or shrinks a given memory block. If p is **nil** then a new
|
## grows or shrinks a given memory block. If p is **nil** then a new
|
||||||
## memory block is returned. In either way the block has at least
|
## memory block is returned. In either way the block has at least
|
||||||
## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not
|
## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not
|
||||||
|
|
@ -1394,7 +1394,7 @@ when not defined(nimrodVM):
|
||||||
## its allocating thread!
|
## its allocating thread!
|
||||||
## Use `resizeShared` to reallocate from a shared heap.
|
## Use `resizeShared` to reallocate from a shared heap.
|
||||||
cast[ptr T](realloc(p, T.sizeof * newSize))
|
cast[ptr T](realloc(p, T.sizeof * newSize))
|
||||||
proc dealloc*(p: pointer) {.noconv, rtl, tags: [], gcsafe.}
|
proc dealloc*(p: pointer) {.noconv, rtl, tags: [], benign.}
|
||||||
## frees the memory allocated with ``alloc``, ``alloc0`` or
|
## frees the memory allocated with ``alloc``, ``alloc0`` or
|
||||||
## ``realloc``. This procedure is dangerous! If one forgets to
|
## ``realloc``. This procedure is dangerous! If one forgets to
|
||||||
## free the memory a leak occurs; if one tries to access freed
|
## free the memory a leak occurs; if one tries to access freed
|
||||||
|
|
@ -1402,23 +1402,23 @@ when not defined(nimrodVM):
|
||||||
## or other memory may be corrupted.
|
## or other memory may be corrupted.
|
||||||
## The freed memory must belong to its allocating thread!
|
## The freed memory must belong to its allocating thread!
|
||||||
## Use `deallocShared` to deallocate from a shared heap.
|
## Use `deallocShared` to deallocate from a shared heap.
|
||||||
proc free*[T](p: ptr T) {.inline, gcsafe.} =
|
proc free*[T](p: ptr T) {.inline, benign.} =
|
||||||
dealloc(p)
|
dealloc(p)
|
||||||
proc allocShared*(size: int): pointer {.noconv, rtl, gcsafe.}
|
proc allocShared*(size: int): pointer {.noconv, rtl, benign.}
|
||||||
## allocates a new memory block on the shared heap with at
|
## allocates a new memory block on the shared heap with at
|
||||||
## least ``size`` bytes. The block has to be freed with
|
## least ``size`` bytes. The block has to be freed with
|
||||||
## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block
|
## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block
|
||||||
## is not initialized, so reading from it before writing to it is
|
## is not initialized, so reading from it before writing to it is
|
||||||
## undefined behaviour!
|
## undefined behaviour!
|
||||||
proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline,
|
proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline,
|
||||||
gcsafe.} =
|
benign.} =
|
||||||
## allocates a new memory block on the shared heap with at
|
## allocates a new memory block on the shared heap with at
|
||||||
## least ``T.sizeof * size`` bytes. The block has to be freed with
|
## least ``T.sizeof * size`` bytes. The block has to be freed with
|
||||||
## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block
|
## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block
|
||||||
## is not initialized, so reading from it before writing to it is
|
## is not initialized, so reading from it before writing to it is
|
||||||
## undefined behaviour!
|
## undefined behaviour!
|
||||||
cast[ptr T](allocShared(T.sizeof * size))
|
cast[ptr T](allocShared(T.sizeof * size))
|
||||||
proc allocShared0*(size: int): pointer {.noconv, rtl, gcsafe.}
|
proc allocShared0*(size: int): pointer {.noconv, rtl, benign.}
|
||||||
## allocates a new memory block on the shared heap with at
|
## allocates a new memory block on the shared heap with at
|
||||||
## least ``size`` bytes. The block has to be freed with
|
## least ``size`` bytes. The block has to be freed with
|
||||||
## ``reallocShared(block, 0)`` or ``deallocShared(block)``.
|
## ``reallocShared(block, 0)`` or ``deallocShared(block)``.
|
||||||
|
|
@ -1432,7 +1432,7 @@ when not defined(nimrodVM):
|
||||||
## containing zero, so it is somewhat safer than ``createSharedU``.
|
## containing zero, so it is somewhat safer than ``createSharedU``.
|
||||||
cast[ptr T](allocShared0(T.sizeof * size))
|
cast[ptr T](allocShared0(T.sizeof * size))
|
||||||
proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl,
|
proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl,
|
||||||
gcsafe.}
|
benign.}
|
||||||
## grows or shrinks a given memory block on the heap. If p is **nil**
|
## grows or shrinks a given memory block on the heap. If p is **nil**
|
||||||
## then a new memory block is returned. In either way the block has at
|
## then a new memory block is returned. In either way the block has at
|
||||||
## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
|
## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
|
||||||
|
|
@ -1445,13 +1445,13 @@ when not defined(nimrodVM):
|
||||||
## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other
|
## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other
|
||||||
## cases the block has to be freed with ``freeShared``.
|
## cases the block has to be freed with ``freeShared``.
|
||||||
cast[ptr T](reallocShared(p, T.sizeof * newSize))
|
cast[ptr T](reallocShared(p, T.sizeof * newSize))
|
||||||
proc deallocShared*(p: pointer) {.noconv, rtl, gcsafe.}
|
proc deallocShared*(p: pointer) {.noconv, rtl, benign.}
|
||||||
## frees the memory allocated with ``allocShared``, ``allocShared0`` or
|
## frees the memory allocated with ``allocShared``, ``allocShared0`` or
|
||||||
## ``reallocShared``. This procedure is dangerous! If one forgets to
|
## ``reallocShared``. This procedure is dangerous! If one forgets to
|
||||||
## free the memory a leak occurs; if one tries to access freed
|
## free the memory a leak occurs; if one tries to access freed
|
||||||
## memory (or just freeing it twice!) a core dump may happen
|
## memory (or just freeing it twice!) a core dump may happen
|
||||||
## or other memory may be corrupted.
|
## or other memory may be corrupted.
|
||||||
proc freeShared*[T](p: ptr T) {.inline, gcsafe.} =
|
proc freeShared*[T](p: ptr T) {.inline, benign.} =
|
||||||
## frees the memory allocated with ``createShared``, ``createSharedU`` or
|
## frees the memory allocated with ``createShared``, ``createSharedU`` or
|
||||||
## ``resizeShared``. This procedure is dangerous! If one forgets to
|
## ``resizeShared``. This procedure is dangerous! If one forgets to
|
||||||
## free the memory a leak occurs; if one tries to access freed
|
## free the memory a leak occurs; if one tries to access freed
|
||||||
|
|
@ -1993,15 +1993,15 @@ when false:
|
||||||
# ----------------- GC interface ---------------------------------------------
|
# ----------------- GC interface ---------------------------------------------
|
||||||
|
|
||||||
when not defined(nimrodVM) and hostOS != "standalone":
|
when not defined(nimrodVM) and hostOS != "standalone":
|
||||||
proc GC_disable*() {.rtl, inl.}
|
proc GC_disable*() {.rtl, inl, benign.}
|
||||||
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
||||||
## reactivate the GC. Note that in most circumstances one should only disable
|
## reactivate the GC. Note that in most circumstances one should only disable
|
||||||
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
||||||
|
|
||||||
proc GC_enable*() {.rtl, inl.}
|
proc GC_enable*() {.rtl, inl, benign.}
|
||||||
## enables the GC again.
|
## enables the GC again.
|
||||||
|
|
||||||
proc GC_fullCollect*() {.rtl.}
|
proc GC_fullCollect*() {.rtl, benign.}
|
||||||
## forces a full garbage collection pass.
|
## forces a full garbage collection pass.
|
||||||
## Ordinary code does not need to call this (and should not).
|
## Ordinary code does not need to call this (and should not).
|
||||||
|
|
||||||
|
|
@ -2014,32 +2014,32 @@ when not defined(nimrodVM) and hostOS != "standalone":
|
||||||
|
|
||||||
{.deprecated: [TGC_Strategy: GC_Strategy].}
|
{.deprecated: [TGC_Strategy: GC_Strategy].}
|
||||||
|
|
||||||
proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated.}
|
proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated, benign.}
|
||||||
## tells the GC the desired strategy for the application.
|
## tells the GC the desired strategy for the application.
|
||||||
## **Deprecated** since version 0.8.14. This has always been a nop.
|
## **Deprecated** since version 0.8.14. This has always been a nop.
|
||||||
|
|
||||||
proc GC_enableMarkAndSweep*() {.rtl.}
|
proc GC_enableMarkAndSweep*() {.rtl, benign.}
|
||||||
proc GC_disableMarkAndSweep*() {.rtl.}
|
proc GC_disableMarkAndSweep*() {.rtl, benign.}
|
||||||
## the current implementation uses a reference counting garbage collector
|
## the current implementation uses a reference counting garbage collector
|
||||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||||
## sweep phase may take a long time and is not needed if the application
|
## sweep phase may take a long time and is not needed if the application
|
||||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||||
## and activated separately from the rest of the GC.
|
## and activated separately from the rest of the GC.
|
||||||
|
|
||||||
proc GC_getStatistics*(): string {.rtl.}
|
proc GC_getStatistics*(): string {.rtl, benign.}
|
||||||
## returns an informative string about the GC's activity. This may be useful
|
## returns an informative string about the GC's activity. This may be useful
|
||||||
## for tweaking.
|
## for tweaking.
|
||||||
|
|
||||||
proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.}
|
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
|
||||||
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.}
|
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
|
||||||
proc GC_ref*(x: string) {.magic: "GCref", gcsafe.}
|
proc GC_ref*(x: string) {.magic: "GCref", benign.}
|
||||||
## marks the object `x` as referenced, so that it will not be freed until
|
## marks the object `x` as referenced, so that it will not be freed until
|
||||||
## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
|
## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
|
||||||
## n calls to `GC_unref` are needed to unmark `x`.
|
## n calls to `GC_unref` are needed to unmark `x`.
|
||||||
|
|
||||||
proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe.}
|
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
|
||||||
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe.}
|
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
|
||||||
proc GC_unref*(x: string) {.magic: "GCunref", gcsafe.}
|
proc GC_unref*(x: string) {.magic: "GCunref", benign.}
|
||||||
## see the documentation of `GC_ref`.
|
## see the documentation of `GC_ref`.
|
||||||
|
|
||||||
template accumulateResult*(iter: expr) =
|
template accumulateResult*(iter: expr) =
|
||||||
|
|
@ -2057,7 +2057,7 @@ const NimStackTrace = compileOption("stacktrace")
|
||||||
# of the code
|
# of the code
|
||||||
|
|
||||||
var
|
var
|
||||||
globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, gcsafe.}
|
globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}
|
||||||
## with this hook you can influence exception handling on a global level.
|
## with this hook you can influence exception handling on a global level.
|
||||||
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
||||||
## application code should never set this hook! You better know what you
|
## application code should never set this hook! You better know what you
|
||||||
|
|
@ -2065,7 +2065,7 @@ var
|
||||||
## exception is caught and does not propagate further through the call
|
## exception is caught and does not propagate further through the call
|
||||||
## stack.
|
## stack.
|
||||||
|
|
||||||
localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, gcsafe.}
|
localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}
|
||||||
## with this hook you can influence exception handling on a
|
## with this hook you can influence exception handling on a
|
||||||
## thread local level.
|
## thread local level.
|
||||||
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
||||||
|
|
@ -2073,7 +2073,7 @@ var
|
||||||
## do when setting this. If ``localRaiseHook`` returns false, the exception
|
## do when setting this. If ``localRaiseHook`` returns false, the exception
|
||||||
## is caught and does not propagate further through the call stack.
|
## is caught and does not propagate further through the call stack.
|
||||||
|
|
||||||
outOfMemHook*: proc () {.nimcall, tags: [], gcsafe.}
|
outOfMemHook*: proc () {.nimcall, tags: [], benign.}
|
||||||
## set this variable to provide a procedure that should be called
|
## set this variable to provide a procedure that should be called
|
||||||
## in case of an `out of memory`:idx: event. The standard handler
|
## in case of an `out of memory`:idx: event. The standard handler
|
||||||
## writes an error message and terminates the program. `outOfMemHook` can
|
## writes an error message and terminates the program. `outOfMemHook` can
|
||||||
|
|
@ -2125,7 +2125,7 @@ elif hostOS != "standalone":
|
||||||
inc(i)
|
inc(i)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe.}
|
proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.}
|
||||||
## Writes and flushes the parameters to the standard output.
|
## Writes and flushes the parameters to the standard output.
|
||||||
##
|
##
|
||||||
## Special built-in that takes a variable number of arguments. Each argument
|
## Special built-in that takes a variable number of arguments. Each argument
|
||||||
|
|
@ -2178,7 +2178,7 @@ when not declared(sysFatal):
|
||||||
e.msg = message & arg
|
e.msg = message & arg
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.}
|
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
|
||||||
## get type information for `x`. Ordinary code should not use this, but
|
## get type information for `x`. Ordinary code should not use this, but
|
||||||
## the `typeinfo` module instead.
|
## the `typeinfo` module instead.
|
||||||
|
|
||||||
|
|
@ -2294,14 +2294,14 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
|
|
||||||
proc open*(f: var File, filename: string,
|
proc open*(f: var File, filename: string,
|
||||||
mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [],
|
mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [],
|
||||||
gcsafe.}
|
benign.}
|
||||||
## Opens a file named `filename` with given `mode`.
|
## Opens a file named `filename` with given `mode`.
|
||||||
##
|
##
|
||||||
## Default mode is readonly. Returns true iff the file could be opened.
|
## Default mode is readonly. Returns true iff the file could be opened.
|
||||||
## This throws no exception if the file could not be opened.
|
## This throws no exception if the file could not be opened.
|
||||||
|
|
||||||
proc open*(f: var File, filehandle: FileHandle,
|
proc open*(f: var File, filehandle: FileHandle,
|
||||||
mode: FileMode = fmRead): bool {.tags: [], gcsafe.}
|
mode: FileMode = fmRead): bool {.tags: [], benign.}
|
||||||
## Creates a ``TFile`` from a `filehandle` with given `mode`.
|
## Creates a ``TFile`` from a `filehandle` with given `mode`.
|
||||||
##
|
##
|
||||||
## Default mode is readonly. Returns true iff the file could be opened.
|
## Default mode is readonly. Returns true iff the file could be opened.
|
||||||
|
|
@ -2316,7 +2316,7 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
sysFatal(IOError, "cannot open: ", filename)
|
sysFatal(IOError, "cannot open: ", filename)
|
||||||
|
|
||||||
proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
|
proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
|
||||||
tags: [], gcsafe.}
|
tags: [], benign.}
|
||||||
## reopens the file `f` with given `filename` and `mode`. This
|
## reopens the file `f` with given `filename` and `mode`. This
|
||||||
## is often used to redirect the `stdin`, `stdout` or `stderr`
|
## is often used to redirect the `stdin`, `stdout` or `stderr`
|
||||||
## file variables.
|
## file variables.
|
||||||
|
|
@ -2326,7 +2326,7 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
proc close*(f: File) {.importc: "fclose", header: "<stdio.h>", tags: [].}
|
proc close*(f: File) {.importc: "fclose", header: "<stdio.h>", tags: [].}
|
||||||
## Closes the file.
|
## Closes the file.
|
||||||
|
|
||||||
proc endOfFile*(f: File): bool {.tags: [], gcsafe.}
|
proc endOfFile*(f: File): bool {.tags: [], benign.}
|
||||||
## Returns true iff `f` is at the end.
|
## Returns true iff `f` is at the end.
|
||||||
|
|
||||||
proc readChar*(f: File): char {.
|
proc readChar*(f: File): char {.
|
||||||
|
|
@ -2336,40 +2336,40 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
importc: "fflush", header: "<stdio.h>", tags: [WriteIOEffect].}
|
importc: "fflush", header: "<stdio.h>", tags: [WriteIOEffect].}
|
||||||
## Flushes `f`'s buffer.
|
## Flushes `f`'s buffer.
|
||||||
|
|
||||||
proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], gcsafe.}
|
proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.}
|
||||||
## Reads all data from the stream `file`.
|
## Reads all data from the stream `file`.
|
||||||
##
|
##
|
||||||
## Raises an IO exception in case of an error. It is an error if the
|
## Raises an IO exception in case of an error. It is an error if the
|
||||||
## current file position is not at the beginning of the file.
|
## current file position is not at the beginning of the file.
|
||||||
|
|
||||||
proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], gcsafe.}
|
proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.}
|
||||||
## Opens a file named `filename` for reading. Then calls `readAll`
|
## Opens a file named `filename` for reading. Then calls `readAll`
|
||||||
## and closes the file afterwards. Returns the string.
|
## and closes the file afterwards. Returns the string.
|
||||||
## Raises an IO exception in case of an error.
|
## Raises an IO exception in case of an error.
|
||||||
|
|
||||||
proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], gcsafe.}
|
proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.}
|
||||||
## Opens a file named `filename` for writing. Then writes the
|
## Opens a file named `filename` for writing. Then writes the
|
||||||
## `content` completely to the file and closes the file afterwards.
|
## `content` completely to the file and closes the file afterwards.
|
||||||
## Raises an IO exception in case of an error.
|
## Raises an IO exception in case of an error.
|
||||||
|
|
||||||
proc write*(f: File, r: float32) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, r: float32) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, i: int) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, i: int) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, s: string) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, s: string) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, b: bool) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, b: bool) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, c: char) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, c: char) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], benign.}
|
||||||
proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], gcsafe.}
|
proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], benign.}
|
||||||
## Writes a value to the file `f`. May throw an IO exception.
|
## Writes a value to the file `f`. May throw an IO exception.
|
||||||
|
|
||||||
proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], gcsafe.}
|
proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], benign.}
|
||||||
## reads a line of text from the file `f`. May throw an IO exception.
|
## reads a line of text from the file `f`. May throw an IO exception.
|
||||||
## A line of text may be delimited by ``CR``, ``LF`` or
|
## A line of text may be delimited by ``CR``, ``LF`` or
|
||||||
## ``CRLF``. The newline character(s) are not part of the returned string.
|
## ``CRLF``. The newline character(s) are not part of the returned string.
|
||||||
|
|
||||||
proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
|
proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
|
||||||
gcsafe.}
|
benign.}
|
||||||
## reads a line of text from the file `f` into `line`. `line` must not be
|
## reads a line of text from the file `f` into `line`. `line` must not be
|
||||||
## ``nil``! May throw an IO exception.
|
## ``nil``! May throw an IO exception.
|
||||||
## A line of text may be delimited by ``CR``, ``LF`` or
|
## A line of text may be delimited by ``CR``, ``LF`` or
|
||||||
|
|
@ -2379,57 +2379,57 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
|
|
||||||
when not defined(booting):
|
when not defined(booting):
|
||||||
proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
|
proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
|
||||||
tags: [WriteIOEffect], gcsafe.}
|
tags: [WriteIOEffect], benign.}
|
||||||
## writes the values `x` to `f` and then writes "\n".
|
## writes the values `x` to `f` and then writes "\n".
|
||||||
## May throw an IO exception.
|
## May throw an IO exception.
|
||||||
else:
|
else:
|
||||||
proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
|
proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
|
||||||
tags: [WriteIOEffect].}
|
tags: [WriteIOEffect].}
|
||||||
|
|
||||||
proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], gcsafe.}
|
proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.}
|
||||||
## retrieves the file size (in bytes) of `f`.
|
## retrieves the file size (in bytes) of `f`.
|
||||||
|
|
||||||
proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {.
|
proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {.
|
||||||
tags: [ReadIOEffect], gcsafe.}
|
tags: [ReadIOEffect], benign.}
|
||||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||||
## the actual number of bytes that have been read which may be less than
|
## the actual number of bytes that have been read which may be less than
|
||||||
## `len` (if not as many bytes are remaining), but not greater.
|
## `len` (if not as many bytes are remaining), but not greater.
|
||||||
|
|
||||||
proc readChars*(f: File, a: var openArray[char], start, len: int): int {.
|
proc readChars*(f: File, a: var openArray[char], start, len: int): int {.
|
||||||
tags: [ReadIOEffect], gcsafe.}
|
tags: [ReadIOEffect], benign.}
|
||||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||||
## the actual number of bytes that have been read which may be less than
|
## the actual number of bytes that have been read which may be less than
|
||||||
## `len` (if not as many bytes are remaining), but not greater.
|
## `len` (if not as many bytes are remaining), but not greater.
|
||||||
|
|
||||||
proc readBuffer*(f: File, buffer: pointer, len: int): int {.
|
proc readBuffer*(f: File, buffer: pointer, len: int): int {.
|
||||||
tags: [ReadIOEffect], gcsafe.}
|
tags: [ReadIOEffect], benign.}
|
||||||
## reads `len` bytes into the buffer pointed to by `buffer`. Returns
|
## reads `len` bytes into the buffer pointed to by `buffer`. Returns
|
||||||
## the actual number of bytes that have been read which may be less than
|
## the actual number of bytes that have been read which may be less than
|
||||||
## `len` (if not as many bytes are remaining), but not greater.
|
## `len` (if not as many bytes are remaining), but not greater.
|
||||||
|
|
||||||
proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {.
|
proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {.
|
||||||
tags: [WriteIOEffect], gcsafe.}
|
tags: [WriteIOEffect], benign.}
|
||||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||||
## the number of actual written bytes, which may be less than `len` in case
|
## the number of actual written bytes, which may be less than `len` in case
|
||||||
## of an error.
|
## of an error.
|
||||||
|
|
||||||
proc writeChars*(f: File, a: openArray[char], start, len: int): int {.
|
proc writeChars*(f: File, a: openArray[char], start, len: int): int {.
|
||||||
tags: [WriteIOEffect], gcsafe.}
|
tags: [WriteIOEffect], benign.}
|
||||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||||
## the number of actual written bytes, which may be less than `len` in case
|
## the number of actual written bytes, which may be less than `len` in case
|
||||||
## of an error.
|
## of an error.
|
||||||
|
|
||||||
proc writeBuffer*(f: File, buffer: pointer, len: int): int {.
|
proc writeBuffer*(f: File, buffer: pointer, len: int): int {.
|
||||||
tags: [WriteIOEffect], gcsafe.}
|
tags: [WriteIOEffect], benign.}
|
||||||
## writes the bytes of buffer pointed to by the parameter `buffer` to the
|
## writes the bytes of buffer pointed to by the parameter `buffer` to the
|
||||||
## file `f`. Returns the number of actual written bytes, which may be less
|
## file `f`. Returns the number of actual written bytes, which may be less
|
||||||
## than `len` in case of an error.
|
## than `len` in case of an error.
|
||||||
|
|
||||||
proc setFilePos*(f: File, pos: int64) {.gcsafe.}
|
proc setFilePos*(f: File, pos: int64) {.benign.}
|
||||||
## sets the position of the file pointer that is used for read/write
|
## sets the position of the file pointer that is used for read/write
|
||||||
## operations. The file's first byte has the index zero.
|
## operations. The file's first byte has the index zero.
|
||||||
|
|
||||||
proc getFilePos*(f: File): int64 {.gcsafe.}
|
proc getFilePos*(f: File): int64 {.benign.}
|
||||||
## retrieves the current position of the file pointer that is used to
|
## retrieves the current position of the file pointer that is used to
|
||||||
## read from the file `f`. The file's first byte has the index zero.
|
## read from the file `f`. The file's first byte has the index zero.
|
||||||
|
|
||||||
|
|
@ -2476,11 +2476,11 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
|
|
||||||
when not defined(NimrodVM):
|
when not defined(NimrodVM):
|
||||||
proc atomicInc*(memLoc: var int, x: int = 1): int {.inline,
|
proc atomicInc*(memLoc: var int, x: int = 1): int {.inline,
|
||||||
discardable, gcsafe.}
|
discardable, benign.}
|
||||||
## atomic increment of `memLoc`. Returns the value after the operation.
|
## atomic increment of `memLoc`. Returns the value after the operation.
|
||||||
|
|
||||||
proc atomicDec*(memLoc: var int, x: int = 1): int {.inline,
|
proc atomicDec*(memLoc: var int, x: int = 1): int {.inline,
|
||||||
discardable, gcsafe.}
|
discardable, benign.}
|
||||||
## atomic decrement of `memLoc`. Returns the value after the operation.
|
## atomic decrement of `memLoc`. Returns the value after the operation.
|
||||||
|
|
||||||
include "system/atomics"
|
include "system/atomics"
|
||||||
|
|
@ -2611,11 +2611,11 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
include "system/assign"
|
include "system/assign"
|
||||||
include "system/repr"
|
include "system/repr"
|
||||||
|
|
||||||
proc getCurrentException*(): ref Exception {.compilerRtl, inl, gcsafe.} =
|
proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =
|
||||||
## retrieves the current exception; if there is none, nil is returned.
|
## retrieves the current exception; if there is none, nil is returned.
|
||||||
result = currException
|
result = currException
|
||||||
|
|
||||||
proc getCurrentExceptionMsg*(): string {.inline, gcsafe.} =
|
proc getCurrentExceptionMsg*(): string {.inline, benign.} =
|
||||||
## retrieves the error message that was attached to the current
|
## retrieves the error message that was attached to the current
|
||||||
## exception; if there is none, "" is returned.
|
## exception; if there is none, "" is returned.
|
||||||
var e = getCurrentException()
|
var e = getCurrentException()
|
||||||
|
|
@ -2631,7 +2631,7 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
excHandler.hasRaiseAction = true
|
excHandler.hasRaiseAction = true
|
||||||
excHandler.raiseAction = action
|
excHandler.raiseAction = action
|
||||||
|
|
||||||
proc setCurrentException*(exc: ref Exception) {.inline, gcsafe.} =
|
proc setCurrentException*(exc: ref Exception) {.inline, benign.} =
|
||||||
## sets the current exception.
|
## sets the current exception.
|
||||||
##
|
##
|
||||||
## **Warning**: Only use this if you know what you are doing.
|
## **Warning**: Only use this if you know what you are doing.
|
||||||
|
|
|
||||||
|
|
@ -514,7 +514,7 @@ proc getSmallChunk(a: var TMemRegion): PSmallChunk =
|
||||||
result = cast[PSmallChunk](res)
|
result = cast[PSmallChunk](res)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
proc isAllocatedPtr(a: TMemRegion, p: pointer): bool
|
proc isAllocatedPtr(a: TMemRegion, p: pointer): bool {.benign.}
|
||||||
|
|
||||||
proc allocInv(a: TMemRegion): bool =
|
proc allocInv(a: TMemRegion): bool =
|
||||||
## checks some (not all yet) invariants of the allocator's data structures.
|
## checks some (not all yet) invariants of the allocator's data structures.
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
proc genericResetAux(dest: pointer, n: ptr TNimNode) {.gcsafe.}
|
proc genericResetAux(dest: pointer, n: ptr TNimNode) {.benign.}
|
||||||
|
|
||||||
proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.gcsafe.}
|
proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.benign.}
|
||||||
proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
|
proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
|
||||||
shallow: bool) {.gcsafe.} =
|
shallow: bool) {.benign.} =
|
||||||
var
|
var
|
||||||
d = cast[ByteAddress](dest)
|
d = cast[ByteAddress](dest)
|
||||||
s = cast[ByteAddress](src)
|
s = cast[ByteAddress](src)
|
||||||
|
|
@ -136,8 +136,8 @@ proc genericAssignOpenArray(dest, src: pointer, len: int,
|
||||||
genericAssign(cast[pointer](d +% i*% mt.base.size),
|
genericAssign(cast[pointer](d +% i*% mt.base.size),
|
||||||
cast[pointer](s +% i*% mt.base.size), mt.base)
|
cast[pointer](s +% i*% mt.base.size), mt.base)
|
||||||
|
|
||||||
proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, gcsafe.}
|
proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, benign.}
|
||||||
proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} =
|
proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} =
|
||||||
var d = cast[ByteAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone: sysAssert(false, "objectInitAux")
|
of nkNone: sysAssert(false, "objectInitAux")
|
||||||
|
|
@ -182,7 +182,7 @@ else:
|
||||||
mixin destroy
|
mixin destroy
|
||||||
for i in countup(0, r.len - 1): destroy(r[i])
|
for i in countup(0, r.len - 1): destroy(r[i])
|
||||||
|
|
||||||
proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, gcsafe.}
|
proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, benign.}
|
||||||
proc genericResetAux(dest: pointer, n: ptr TNimNode) =
|
proc genericResetAux(dest: pointer, n: ptr TNimNode) =
|
||||||
var d = cast[ByteAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ proc split(t: var PAvlNode) =
|
||||||
t.link[0] = temp
|
t.link[0] = temp
|
||||||
inc t.level
|
inc t.level
|
||||||
|
|
||||||
proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} =
|
proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
|
||||||
if t == bottom:
|
if t == bottom:
|
||||||
t = allocAvlNode(a, key, upperBound)
|
t = allocAvlNode(a, key, upperBound)
|
||||||
else:
|
else:
|
||||||
|
|
@ -64,7 +64,7 @@ proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} =
|
||||||
skew(t)
|
skew(t)
|
||||||
split(t)
|
split(t)
|
||||||
|
|
||||||
proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.gcsafe.} =
|
proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.benign.} =
|
||||||
if t == bottom: return
|
if t == bottom: return
|
||||||
a.last = t
|
a.last = t
|
||||||
if x <% t.key:
|
if x <% t.key:
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
# Headers for procs that the code generator depends on ("compilerprocs")
|
# Headers for procs that the code generator depends on ("compilerprocs")
|
||||||
|
|
||||||
proc addChar(s: NimString, c: char): NimString {.compilerProc, gcsafe.}
|
proc addChar(s: NimString, c: char): NimString {.compilerProc, benign.}
|
||||||
|
|
||||||
type
|
type
|
||||||
TLibHandle = pointer # private type
|
TLibHandle = pointer # private type
|
||||||
|
|
@ -21,5 +21,5 @@ proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
|
||||||
|
|
||||||
proc nimLoadLibraryError(path: string) {.compilerproc, noinline.}
|
proc nimLoadLibraryError(path: string) {.compilerproc, noinline.}
|
||||||
|
|
||||||
proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, gcsafe.}
|
proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, benign.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ proc deinitRawChannel(p: pointer) =
|
||||||
deinitSysCond(c.cond)
|
deinitSysCond(c.cond)
|
||||||
|
|
||||||
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
||||||
mode: TLoadStoreMode) {.gcsafe.}
|
mode: TLoadStoreMode) {.benign.}
|
||||||
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
|
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
|
||||||
mode: TLoadStoreMode) {.gcsafe.} =
|
mode: TLoadStoreMode) {.benign.} =
|
||||||
var
|
var
|
||||||
d = cast[ByteAddress](dest)
|
d = cast[ByteAddress](dest)
|
||||||
s = cast[ByteAddress](src)
|
s = cast[ByteAddress](src)
|
||||||
|
|
@ -225,15 +225,15 @@ proc recv*[TMsg](c: var TChannel[TMsg]): TMsg =
|
||||||
acquireSys(q.lock)
|
acquireSys(q.lock)
|
||||||
llRecv(q, addr(result), cast[PNimType](getTypeInfo(result)))
|
llRecv(q, addr(result), cast[PNimType](getTypeInfo(result)))
|
||||||
releaseSys(q.lock)
|
releaseSys(q.lock)
|
||||||
|
|
||||||
proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool,
|
proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool,
|
||||||
msg: TMsg] =
|
msg: TMsg] =
|
||||||
## try to receives a message from the channel `c` if available. Otherwise
|
## try to receives a message from the channel `c` if available. Otherwise
|
||||||
## it returns ``(false, default(msg))``.
|
## it returns ``(false, default(msg))``.
|
||||||
var q = cast[PRawChannel](addr(c))
|
var q = cast[PRawChannel](addr(c))
|
||||||
if q.mask != ChannelDeadMask:
|
if q.mask != ChannelDeadMask:
|
||||||
if tryAcquireSys(q.lock):
|
if tryAcquireSys(q.lock):
|
||||||
llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))
|
llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))
|
||||||
result.dataAvailable = true
|
result.dataAvailable = true
|
||||||
releaseSys(q.lock)
|
releaseSys(q.lock)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.gcsafe.}
|
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.}
|
||||||
proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.gcsafe.} =
|
proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} =
|
||||||
var
|
var
|
||||||
d = cast[ByteAddress](dest)
|
d = cast[ByteAddress](dest)
|
||||||
s = cast[ByteAddress](src)
|
s = cast[ByteAddress](src)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
# use the heap (and nor exceptions) do not include the GC or memory allocator.
|
# use the heap (and nor exceptions) do not include the GC or memory allocator.
|
||||||
|
|
||||||
var
|
var
|
||||||
errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], gcsafe.})
|
errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], benign.})
|
||||||
## Function that will be called
|
## Function that will be called
|
||||||
## instead of stdmsg.write when printing stacktrace.
|
## instead of stdmsg.write when printing stacktrace.
|
||||||
## Unstable API.
|
## Unstable API.
|
||||||
|
|
@ -32,10 +32,10 @@ proc showErrorMessage(data: cstring) =
|
||||||
else:
|
else:
|
||||||
writeToStdErr(data)
|
writeToStdErr(data)
|
||||||
|
|
||||||
proc chckIndx(i, a, b: int): int {.inline, compilerproc, gcsafe.}
|
proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
|
||||||
proc chckRange(i, a, b: int): int {.inline, compilerproc, gcsafe.}
|
proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
|
||||||
proc chckRangeF(x, a, b: float): float {.inline, compilerproc, gcsafe.}
|
proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.}
|
||||||
proc chckNil(p: pointer) {.noinline, compilerproc, gcsafe.}
|
proc chckNil(p: pointer) {.noinline, compilerproc, benign.}
|
||||||
|
|
||||||
var
|
var
|
||||||
framePtr {.threadvar.}: PFrame
|
framePtr {.threadvar.}: PFrame
|
||||||
|
|
@ -343,5 +343,5 @@ when not defined(noSignalHandler):
|
||||||
|
|
||||||
proc setControlCHook(hook: proc () {.noconv.}) =
|
proc setControlCHook(hook: proc () {.noconv.}) =
|
||||||
# ugly cast, but should work on all architectures:
|
# ugly cast, but should work on all architectures:
|
||||||
type TSignalHandler = proc (sig: cint) {.noconv, gcsafe.}
|
type TSignalHandler = proc (sig: cint) {.noconv, benign.}
|
||||||
c_signal(SIGINT, cast[TSignalHandler](hook))
|
c_signal(SIGINT, cast[TSignalHandler](hook))
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ type
|
||||||
waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack,
|
waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack,
|
||||||
waCollectWhite,
|
waCollectWhite,
|
||||||
|
|
||||||
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.}
|
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.}
|
||||||
# A ref type can have a finalizer that is called before the object's
|
# A ref type can have a finalizer that is called before the object's
|
||||||
# storage is freed.
|
# storage is freed.
|
||||||
|
|
||||||
|
|
@ -152,11 +152,11 @@ template gcTrace(cell, state: expr): stmt {.immediate.} =
|
||||||
when traceGC: traceCell(cell, state)
|
when traceGC: traceCell(cell, state)
|
||||||
|
|
||||||
# forward declarations:
|
# forward declarations:
|
||||||
proc collectCT(gch: var TGcHeap) {.gcsafe.}
|
proc collectCT(gch: var TGcHeap) {.benign.}
|
||||||
proc isOnStack*(p: pointer): bool {.noinline, gcsafe.}
|
proc isOnStack*(p: pointer): bool {.noinline, benign.}
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.}
|
proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.}
|
||||||
proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.}
|
proc doOperation(p: pointer, op: TWalkOp) {.benign.}
|
||||||
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.}
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.}
|
||||||
# we need the prototype here for debugging purposes
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
when hasThreadSupport and hasSharedHeap:
|
||||||
|
|
@ -294,7 +294,7 @@ proc initGC() =
|
||||||
|
|
||||||
when useMarkForDebug or useBackupGc:
|
when useMarkForDebug or useBackupGc:
|
||||||
type
|
type
|
||||||
TGlobalMarkerProc = proc () {.nimcall, gcsafe.}
|
TGlobalMarkerProc = proc () {.nimcall, benign.}
|
||||||
var
|
var
|
||||||
globalMarkersLen: int
|
globalMarkersLen: int
|
||||||
globalMarkers: array[0.. 7_000, TGlobalMarkerProc]
|
globalMarkers: array[0.. 7_000, TGlobalMarkerProc]
|
||||||
|
|
@ -311,7 +311,7 @@ proc cellsetReset(s: var TCellSet) =
|
||||||
deinit(s)
|
deinit(s)
|
||||||
init(s)
|
init(s)
|
||||||
|
|
||||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
|
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} =
|
||||||
var d = cast[ByteAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
||||||
|
|
@ -680,11 +680,11 @@ proc doOperation(p: pointer, op: TWalkOp) =
|
||||||
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
|
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
|
||||||
doOperation(d, TWalkOp(op))
|
doOperation(d, TWalkOp(op))
|
||||||
|
|
||||||
proc collectZCT(gch: var TGcHeap): bool {.gcsafe.}
|
proc collectZCT(gch: var TGcHeap): bool {.benign.}
|
||||||
|
|
||||||
when useMarkForDebug or useBackupGc:
|
when useMarkForDebug or useBackupGc:
|
||||||
proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl,
|
proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl,
|
||||||
gcsafe.}
|
benign.}
|
||||||
|
|
||||||
proc collectRoots(gch: var TGcHeap) =
|
proc collectRoots(gch: var TGcHeap) =
|
||||||
for s in elements(gch.cycleRoots):
|
for s in elements(gch.cycleRoots):
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ type
|
||||||
# local
|
# local
|
||||||
waMarkPrecise # fast precise marking
|
waMarkPrecise # fast precise marking
|
||||||
|
|
||||||
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.}
|
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.}
|
||||||
# A ref type can have a finalizer that is called before the object's
|
# A ref type can have a finalizer that is called before the object's
|
||||||
# storage is freed.
|
# storage is freed.
|
||||||
|
|
||||||
TGlobalMarkerProc = proc () {.nimcall, gcsafe.}
|
TGlobalMarkerProc = proc () {.nimcall, benign.}
|
||||||
|
|
||||||
TGcStat = object
|
TGcStat = object
|
||||||
collections: int # number of performed full collections
|
collections: int # number of performed full collections
|
||||||
|
|
@ -116,11 +116,11 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
|
||||||
{.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
|
{.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
|
||||||
|
|
||||||
# forward declarations:
|
# forward declarations:
|
||||||
proc collectCT(gch: var TGcHeap) {.gcsafe.}
|
proc collectCT(gch: var TGcHeap) {.benign.}
|
||||||
proc isOnStack*(p: pointer): bool {.noinline, gcsafe.}
|
proc isOnStack*(p: pointer): bool {.noinline, benign.}
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.}
|
proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.}
|
||||||
proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.}
|
proc doOperation(p: pointer, op: TWalkOp) {.benign.}
|
||||||
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.}
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.}
|
||||||
# we need the prototype here for debugging purposes
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
proc prepareDealloc(cell: PCell) =
|
proc prepareDealloc(cell: PCell) =
|
||||||
|
|
@ -168,7 +168,7 @@ proc initGC() =
|
||||||
Init(gch.allocated)
|
Init(gch.allocated)
|
||||||
init(gch.marked)
|
init(gch.marked)
|
||||||
|
|
||||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
|
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} =
|
||||||
var d = cast[ByteAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,8 @@ type
|
||||||
base: ptr TNimType
|
base: ptr TNimType
|
||||||
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
||||||
finalizer: pointer # the finalizer for the type
|
finalizer: pointer # the finalizer for the type
|
||||||
marker: proc (p: pointer, op: int) {.nimcall, gcsafe.} # marker proc for GC
|
marker: proc (p: pointer, op: int) {.nimcall, benign.} # marker proc for GC
|
||||||
deepcopy: proc (p: pointer): pointer {.nimcall, gcsafe.}
|
deepcopy: proc (p: pointer): pointer {.nimcall, benign.}
|
||||||
PNimType = ptr TNimType
|
PNimType = ptr TNimType
|
||||||
|
|
||||||
# node.len may be the ``first`` element of a set
|
# node.len may be the ``first`` element of a set
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,8 @@ else:
|
||||||
|
|
||||||
when not defined(nimsuperops):
|
when not defined(nimsuperops):
|
||||||
{.pragma: operator.}
|
{.pragma: operator.}
|
||||||
|
|
||||||
|
when defined(nimlocks):
|
||||||
|
{.pragma: benign, gcsafe, locks: 0.}
|
||||||
|
else:
|
||||||
|
{.pragma: benign, gcsafe.}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue