replace benign with gcsafe (#25527)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit 15c6249f2c)
This commit is contained in:
ringabout
2026-02-20 23:41:06 +08:00
committed by narimiran
parent 74b30de1c6
commit 8f7fd28692
24 changed files with 159 additions and 159 deletions

View File

@@ -433,15 +433,15 @@ when defined(nimHasNoReturnError):
else:
{.pragma: errorNoReturn.}
proc error*(msg: string, n: NimNode = nil) {.magic: "NError", benign, errorNoReturn.}
proc error*(msg: string, n: NimNode = nil) {.magic: "NError", gcsafe, errorNoReturn.}
## Writes an error message at compile time. The optional `n: NimNode`
## parameter is used as the source for file and line number information in
## the compilation error message.
proc warning*(msg: string, n: NimNode = nil) {.magic: "NWarning", benign.}
proc warning*(msg: string, n: NimNode = nil) {.magic: "NWarning", gcsafe.}
## Writes a warning message at compile time.
proc hint*(msg: string, n: NimNode = nil) {.magic: "NHint", benign.}
proc hint*(msg: string, n: NimNode = nil) {.magic: "NHint", gcsafe.}
## Writes a hint message at compile time.
proc newStrLitNode*(s: string): NimNode {.noSideEffect.} =
@@ -511,7 +511,7 @@ proc genSym*(kind: NimSymKind = nskLet; ident = ""): NimNode {.
## Generates a fresh symbol that is guaranteed to be unique. The symbol
## needs to occur in a declaration context.
proc callsite*(): NimNode {.magic: "NCallSite", benign, deprecated:
proc callsite*(): NimNode {.magic: "NCallSite", gcsafe, deprecated:
"Deprecated since v0.18.1; use `varargs[untyped]` in the macro prototype instead".}
## Returns the AST of the invocation expression that invoked this macro.
# see https://github.com/nim-lang/RFCs/issues/387 as candidate replacement.
@@ -933,7 +933,7 @@ proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
const collapseSymChoice = not defined(nimLegacyMacrosCollapseSymChoice)
proc treeTraverse(n: NimNode; res: var string; level = 0; isLisp = false, indented = false) {.benign.} =
proc treeTraverse(n: NimNode; res: var string; level = 0; isLisp = false, indented = false) {.gcsafe.} =
if level > 0:
if indented:
res.add("\n")
@@ -982,21 +982,21 @@ proc treeTraverse(n: NimNode; res: var string; level = 0; isLisp = false, indent
if isLisp:
res.add(")")
proc treeRepr*(n: NimNode): string {.benign.} =
proc treeRepr*(n: NimNode): string {.gcsafe.} =
## Convert the AST `n` to a human-readable tree-like string.
##
## See also `repr`, `lispRepr`_, and `astGenRepr`_.
result = ""
n.treeTraverse(result, isLisp = false, indented = true)
proc lispRepr*(n: NimNode; indented = false): string {.benign.} =
proc lispRepr*(n: NimNode; indented = false): string {.gcsafe.} =
## Convert the AST `n` to a human-readable lisp-like string.
##
## See also `repr`, `treeRepr`_, and `astGenRepr`_.
result = ""
n.treeTraverse(result, isLisp = true, indented = indented)
proc astGenRepr*(n: NimNode): string {.benign.} =
proc astGenRepr*(n: NimNode): string {.gcsafe.} =
## Convert the AST `n` to the code required to generate that AST.
##
## See also `repr`_, `treeRepr`_, and `lispRepr`_.
@@ -1005,7 +1005,7 @@ proc astGenRepr*(n: NimNode): string {.benign.} =
NodeKinds = {nnkEmpty, nnkIdent, nnkSym, nnkNone, nnkCommentStmt}
LitKinds = {nnkCharLit..nnkInt64Lit, nnkFloatLit..nnkFloat64Lit, nnkStrLit..nnkTripleStrLit}
proc traverse(res: var string, level: int, n: NimNode) {.benign.} =
proc traverse(res: var string, level: int, n: NimNode) {.gcsafe.} =
for i in 0..level-1: res.add " "
if n.kind in NodeKinds:
res.add("new" & ($n.kind).substr(3) & "Node(")

View File

@@ -242,7 +242,7 @@ proc rand[T: uint | uint64](r: var Rand; max: T): T =
else:
inc iters
proc rand*(r: var Rand; max: Natural): int {.benign.} =
proc rand*(r: var Rand; max: Natural): int {.gcsafe.} =
## Returns a random integer in the range `0..max` using the given state.
##
## **See also:**
@@ -259,7 +259,7 @@ proc rand*(r: var Rand; max: Natural): int {.benign.} =
cast[int](rand(r, uint64(max)))
# xxx toUnsigned pending https://github.com/nim-lang/Nim/pull/18445
proc rand*(max: int): int {.benign.} =
proc rand*(max: int): int {.gcsafe.} =
## Returns a random integer in the range `0..max`.
##
## If `randomize <#randomize>`_ has not been called, the sequence of random
@@ -280,7 +280,7 @@ proc rand*(max: int): int {.benign.} =
rand(state, max)
proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.benign.} =
proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.gcsafe.} =
## Returns a random floating point number in the range `0.0..max`
## using the given state.
##
@@ -307,7 +307,7 @@ proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.benign.} =
let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
result = (cast[float](u) - 1.0) * max
proc rand*(max: float): float {.benign.} =
proc rand*(max: float): float {.gcsafe.} =
## Returns a random floating point number in the range `0.0..max`.
##
## If `randomize <#randomize>`_ has not been called, the sequence of random
@@ -611,7 +611,7 @@ proc initRand*(seed: int64): Rand =
skipRandomNumbers(result)
discard next(result)
proc randomize*(seed: int64) {.benign.} =
proc randomize*(seed: int64) {.gcsafe.} =
## Initializes the default random number generator with the given seed.
##
## Providing a specific seed will produce the same results for that seed each time.
@@ -735,7 +735,7 @@ when not defined(standalone):
since (1, 5, 1):
export initRand
proc randomize*() {.benign.} =
proc randomize*() {.gcsafe.} =
## Initializes the default random number generator with a seed based on
## random number source.
##

View File

@@ -382,9 +382,9 @@ type
## timezones. The `times` module only supplies implementations for the
## system's local time and UTC.
zonedTimeFromTimeImpl: proc (x: Time): ZonedTime
{.tags: [], raises: [], benign.}
{.tags: [], raises: [], gcsafe.}
zonedTimeFromAdjTimeImpl: proc (x: Time): ZonedTime
{.tags: [], raises: [], benign.}
{.tags: [], raises: [], gcsafe.}
name: string
ZonedTime* = object ## Represents a point in time with an associated
@@ -432,7 +432,7 @@ else:
# Helper procs
#
{.pragma: operator, rtl, noSideEffect, benign.}
{.pragma: operator, rtl, noSideEffect, gcsafe.}
proc convert*[T: SomeInteger](unitFrom, unitTo: FixedTimeUnit, quantity: T): T
{.inline.} =
@@ -518,7 +518,7 @@ proc fromEpochDay(epochday: int64):
return (d.MonthdayRange, m.Month, (y + ord(m <= 2)).int)
proc getDayOfYear*(monthday: MonthdayRange, month: Month, year: int):
YeardayRange {.tags: [], raises: [], benign.} =
YeardayRange {.tags: [], raises: [], gcsafe.} =
## Returns the day of the year.
## Equivalent with `dateTime(year, month, monthday, 0, 0, 0, 0).yearday`.
runnableExamples:
@@ -538,7 +538,7 @@ proc getDayOfYear*(monthday: MonthdayRange, month: Month, year: int):
result = daysUntilMonth[month] + monthday - 1
proc getDayOfWeek*(monthday: MonthdayRange, month: Month, year: int): WeekDay
{.tags: [], raises: [], benign.} =
{.tags: [], raises: [], gcsafe.} =
## Returns the day of the week enum from day, month and year.
## Equivalent with `dateTime(year, month, monthday, 0, 0, 0, 0).weekday`.
runnableExamples:
@@ -922,21 +922,21 @@ proc nanosecond*(time: Time): NanosecondRange =
time.nanosecond
proc fromUnix*(unix: int64): Time
{.benign, tags: [], raises: [], noSideEffect.} =
{.gcsafe, tags: [], raises: [], noSideEffect.} =
## Convert a unix timestamp (seconds since `1970-01-01T00:00:00Z`)
## to a `Time`.
runnableExamples:
doAssert $fromUnix(0).utc == "1970-01-01T00:00:00Z"
initTime(unix, 0)
proc toUnix*(t: Time): int64 {.benign, tags: [], raises: [], noSideEffect.} =
proc toUnix*(t: Time): int64 {.gcsafe, tags: [], raises: [], noSideEffect.} =
## Convert `t` to a unix timestamp (seconds since `1970-01-01T00:00:00Z`).
## See also `toUnixFloat` for subsecond resolution.
runnableExamples:
doAssert fromUnix(0).toUnix() == 0
t.seconds
proc fromUnixFloat(seconds: float): Time {.benign, tags: [], raises: [], noSideEffect.} =
proc fromUnixFloat(seconds: float): Time {.gcsafe, tags: [], raises: [], noSideEffect.} =
## Convert a unix timestamp in seconds to a `Time`; same as `fromUnix`
## but with subsecond resolution.
runnableExamples:
@@ -946,7 +946,7 @@ proc fromUnixFloat(seconds: float): Time {.benign, tags: [], raises: [], noSideE
let nsecs = (seconds - secs) * 1e9
initTime(secs.int64, nsecs.NanosecondRange)
proc toUnixFloat(t: Time): float {.benign, tags: [], raises: [].} =
proc toUnixFloat(t: Time): float {.gcsafe, tags: [], raises: [].} =
## Same as `toUnix` but using subsecond resolution.
runnableExamples:
let t = getTime()
@@ -975,7 +975,7 @@ proc toWinTime*(t: Time): int64 =
proc getTimeImpl(typ: typedesc[Time]): Time =
raiseAssert "implemented in the vm"
proc getTime*(): Time {.tags: [TimeEffect], benign.} =
proc getTime*(): Time {.tags: [TimeEffect], gcsafe.} =
## Gets the current time as a `Time` with up to nanosecond resolution.
when nimvm:
result = getTimeImpl(Time)
@@ -1154,7 +1154,7 @@ proc isLeapDay*(dt: DateTime): bool {.since: (1, 1).} =
assertDateTimeInitialized dt
dt.year.isLeapYear and dt.month == mFeb and dt.monthday == 29
proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} =
proc toTime*(dt: DateTime): Time {.tags: [], raises: [], gcsafe.} =
## Converts a `DateTime` to a `Time` representing the same point in time.
assertDateTimeInitialized dt
let epochDay = toEpochDay(dt.monthday, dt.month, dt.year)
@@ -1197,9 +1197,9 @@ proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime =
proc newTimezone*(
name: string,
zonedTimeFromTimeImpl: proc (time: Time): ZonedTime
{.tags: [], raises: [], benign.},
{.tags: [], raises: [], gcsafe.},
zonedTimeFromAdjTimeImpl: proc (adjTime: Time): ZonedTime
{.tags: [], raises: [], benign.}
{.tags: [], raises: [], gcsafe.}
): owned Timezone =
## Create a new `Timezone`.
##
@@ -1263,12 +1263,12 @@ proc `==`*(zone1, zone2: Timezone): bool =
zone1.name == zone2.name
proc inZone*(time: Time, zone: Timezone): DateTime
{.tags: [], raises: [], benign.} =
{.tags: [], raises: [], gcsafe.} =
## Convert `time` into a `DateTime` using `zone` as the timezone.
result = initDateTime(zone.zonedTimeFromTime(time), zone)
proc inZone*(dt: DateTime, zone: Timezone): DateTime
{.tags: [], raises: [], benign.} =
{.tags: [], raises: [], gcsafe.} =
## Returns a `DateTime` representing the same point in time as `dt` but
## using `zone` as the timezone.
assertDateTimeInitialized dt
@@ -1283,14 +1283,14 @@ proc toAdjTime(dt: DateTime): Time =
result = initTime(seconds, dt.nanosecond)
when defined(js):
proc localZonedTimeFromTime(time: Time): ZonedTime {.benign.} =
proc localZonedTimeFromTime(time: Time): ZonedTime {.gcsafe.} =
let jsDate = newDate(time.seconds * 1000)
let offset = jsDate.getTimezoneOffset() * secondsInMin
result.time = time
result.utcOffset = offset
result.isDst = false
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.benign.} =
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.gcsafe.} =
let utcDate = newDate(adjTime.seconds * 1000)
let localDate = newDate(utcDate.getUTCFullYear(), utcDate.getUTCMonth(),
utcDate.getUTCDate(), utcDate.getUTCHours(), utcDate.getUTCMinutes(),
@@ -1337,11 +1337,11 @@ else:
return ((a.int64 - tm.toAdjUnix).int, tm.tm_isdst > 0)
return (0, false)
proc localZonedTimeFromTime(time: Time): ZonedTime {.benign.} =
proc localZonedTimeFromTime(time: Time): ZonedTime {.gcsafe.} =
let (offset, dst) = getLocalOffsetAndDst(time.seconds)
result = ZonedTime(time: time, utcOffset: offset, isDst: dst)
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.benign.} =
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.gcsafe.} =
var adjUnix = adjTime.seconds
let past = adjUnix - secondsInDay
let (pastOffset, _) = getLocalOffsetAndDst(past)
@@ -1408,7 +1408,7 @@ proc local*(t: Time): DateTime =
## Shorthand for `t.inZone(local())`.
t.inZone(local())
proc now*(): DateTime {.tags: [TimeEffect], benign.} =
proc now*(): DateTime {.tags: [TimeEffect], gcsafe.} =
## Get the current time as a `DateTime` in the local timezone.
## Shorthand for `getTime().local`.
##
@@ -2327,7 +2327,7 @@ proc parseTime*(input: string, f: static[string], zone: Timezone): Time
const f2 = initTimeFormat(f)
result = input.parse(f2, zone).toTime()
proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
proc `$`*(dt: DateTime): string {.tags: [], raises: [], gcsafe.} =
## Converts a `DateTime` object to a string representation.
## It uses the format `yyyy-MM-dd'T'HH:mm:sszzz`.
runnableExamples:
@@ -2339,7 +2339,7 @@ proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} =
else:
result = format(dt, "yyyy-MM-dd'T'HH:mm:sszzz")
proc `$`*(time: Time): string {.tags: [], raises: [], benign.} =
proc `$`*(time: Time): string {.tags: [], raises: [], gcsafe.} =
## Converts a `Time` value to a string representation. It will use the local
## time zone and use the format `yyyy-MM-dd'T'HH:mm:sszzz`.
runnableExamples:

View File

@@ -331,7 +331,7 @@ proc rawRemoveDir(dir: string) {.noWeirdTarget.} =
if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError(), dir)
proc removeDir*(dir: string, checkDir = false) {.rtl, extern: "nos$1", tags: [
WriteDirEffect, ReadDirEffect], benign, noWeirdTarget.} =
WriteDirEffect, ReadDirEffect], gcsafe, noWeirdTarget.} =
## Removes the directory `dir` including all subdirectories and files
## in `dir` (recursively).
##
@@ -441,7 +441,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1",
discard existsOrCreateDir(p)
proc copyDir*(source, dest: string, skipSpecial = false) {.rtl, extern: "nos$1",
tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect], benign, noWeirdTarget.} =
tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect], gcsafe, noWeirdTarget.} =
## Copies a directory from `source` to `dest`.
##
## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks
@@ -482,7 +482,7 @@ proc copyDirWithPermissions*(source, dest: string,
ignorePermissionErrors = true,
skipSpecial = false)
{.rtl, extern: "nos$1", tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect],
benign, noWeirdTarget.} =
gcsafe, noWeirdTarget.} =
## Copies a directory from `source` to `dest` preserving file permissions.
##
## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks

View File

@@ -182,7 +182,7 @@ proc checkErr(f: File) =
{.push stackTrace: off, profiler: off.}
proc readBuffer*(f: File, buffer: pointer, len: Natural): int {.
tags: [ReadIOEffect], benign.} =
tags: [ReadIOEffect], gcsafe.} =
## 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
## `len` (if not as many bytes are remaining), but not greater.
@@ -191,20 +191,20 @@ proc readBuffer*(f: File, buffer: pointer, len: Natural): int {.
proc readBytes*(f: File, a: var openArray[int8|uint8], start,
len: Natural): int {.
tags: [ReadIOEffect], benign.} =
tags: [ReadIOEffect], gcsafe.} =
## 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
## `len` (if not as many bytes are remaining), but not greater.
result = readBuffer(f, addr(a[start]), len)
proc readChars*(f: File, a: var openArray[char]): int {.tags: [ReadIOEffect], benign.} =
proc readChars*(f: File, a: var openArray[char]): int {.tags: [ReadIOEffect], gcsafe.} =
## Reads up to `a.len` bytes into the buffer `a`. Returns
## the actual number of bytes that have been read which may be less than
## `a.len` (if not as many bytes are remaining), but not greater.
result = readBuffer(f, addr(a[0]), a.len)
proc readChars*(f: File, a: var openArray[char], start, len: Natural): int {.
tags: [ReadIOEffect], benign, deprecated:
tags: [ReadIOEffect], gcsafe, deprecated:
"use other `readChars` overload, possibly via: readChars(toOpenArray(buf, start, len-1))".} =
## 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
@@ -213,13 +213,13 @@ proc readChars*(f: File, a: var openArray[char], start, len: Natural): int {.
raiseEIO("buffer overflow: (start+len) > length of openarray buffer")
result = readBuffer(f, addr(a[start]), len)
proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], gcsafe.} =
## Writes a value to the file `f`. May throw an IO exception.
discard c_fputs(c, f)
checkErr(f)
proc writeBuffer*(f: File, buffer: pointer, len: Natural): int {.
tags: [WriteIOEffect], benign.} =
tags: [WriteIOEffect], gcsafe.} =
## 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
## than `len` in case of an error.
@@ -227,7 +227,7 @@ proc writeBuffer*(f: File, buffer: pointer, len: Natural): int {.
checkErr(f)
proc writeBytes*(f: File, a: openArray[int8|uint8], start, len: Natural): int {.
tags: [WriteIOEffect], benign.} =
tags: [WriteIOEffect], gcsafe.} =
## 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
## of an error.
@@ -235,7 +235,7 @@ proc writeBytes*(f: File, a: openArray[int8|uint8], start, len: Natural): int {.
result = writeBuffer(f, addr(x[int(start)]), len)
proc writeChars*(f: File, a: openArray[char], start, len: Natural): int {.
tags: [WriteIOEffect], benign.} =
tags: [WriteIOEffect], gcsafe.} =
## 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
## of an error.
@@ -264,7 +264,7 @@ when defined(windows):
break
inc i, w
proc write*(f: File, s: string) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, s: string) {.tags: [WriteIOEffect], gcsafe.} =
when defined(windows):
writeWindows(f, s, doRaise = true)
else:
@@ -393,7 +393,7 @@ when defined(nimdoc) or (defined(posix) and not defined(nimscript)) or defined(w
inheritable.WinDWORD) != 0
proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
benign.} =
gcsafe.} =
## Reads a line of text from the file `f` into `line`. May throw an IO
## exception.
## A line of text may be delimited by `LF` or `CRLF`. The newline
@@ -519,43 +519,43 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
sp = 128 # read in 128 bytes at a time
line.setLen(pos+sp)
proc readLine*(f: File): string {.tags: [ReadIOEffect], benign.} =
proc readLine*(f: File): string {.tags: [ReadIOEffect], gcsafe.} =
## Reads a line of text from the file `f`. May throw an IO exception.
## A line of text may be delimited by `LF` or `CRLF`. The newline
## character(s) are not part of the returned string.
result = newStringOfCap(80)
if not readLine(f, result): raiseEOF()
proc write*(f: File, i: int) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, i: int) {.tags: [WriteIOEffect], gcsafe.} =
when sizeof(int) == 8:
if c_fprintf(f, "%lld", i) < 0: checkErr(f)
else:
if c_fprintf(f, "%ld", i) < 0: checkErr(f)
proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], gcsafe.} =
when sizeof(BiggestInt) == 8:
if c_fprintf(f, "%lld", i) < 0: checkErr(f)
else:
if c_fprintf(f, "%ld", i) < 0: checkErr(f)
proc write*(f: File, b: bool) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, b: bool) {.tags: [WriteIOEffect], gcsafe.} =
if b: write(f, "true")
else: write(f, "false")
proc write*(f: File, r: float32) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, r: float32) {.tags: [WriteIOEffect], gcsafe.} =
var buffer {.noinit.}: array[65, char]
discard writeFloatToBuffer(buffer, r)
if c_fprintf(f, "%s", buffer[0].addr) < 0: checkErr(f)
proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], gcsafe.} =
var buffer {.noinit.}: array[65, char]
discard writeFloatToBuffer(buffer, r)
if c_fprintf(f, "%s", buffer[0].addr) < 0: checkErr(f)
proc write*(f: File, c: char) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, c: char) {.tags: [WriteIOEffect], gcsafe.} =
discard c_putc(cint(c), f)
proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], benign.} =
proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], gcsafe.} =
for x in items(a): write(f, x)
proc readAllBuffer(file: File): string =
@@ -579,7 +579,7 @@ proc rawFileSize(file: File): int64 =
result = c_ftell(file)
discard c_fseek(file, oldPos, 0)
proc endOfFile*(f: File): bool {.tags: [], benign.} =
proc endOfFile*(f: File): bool {.tags: [], gcsafe.} =
## Returns true if `f` is at the end.
var c = c_fgetc(f)
discard c_ungetc(c, f)
@@ -603,7 +603,7 @@ proc readAllFile(file: File): string =
var len = rawFileSize(file)
result = readAllFile(file, len)
proc readAll*(file: File): string {.tags: [ReadIOEffect], benign.} =
proc readAll*(file: File): string {.tags: [ReadIOEffect], gcsafe.} =
## Reads all data from the stream `file`.
##
## Raises an IO exception in case of an error. It is an error if the
@@ -621,7 +621,7 @@ proc readAll*(file: File): string {.tags: [ReadIOEffect], benign.} =
result = readAllBuffer(file)
proc writeLine*[Ty](f: File, x: varargs[Ty, `$`]) {.inline,
tags: [WriteIOEffect], benign.} =
tags: [WriteIOEffect], gcsafe.} =
## Writes the values `x` to `f` and then writes "\\n".
## May throw an IO exception.
for i in items(x):
@@ -713,7 +713,7 @@ when defined(posix) and not defined(nimscript):
proc open*(f: var File, filename: string,
mode: FileMode = fmRead,
bufSize: int = -1): bool {.tags: [], raises: [], benign.} =
bufSize: int = -1): bool {.tags: [], raises: [], gcsafe.} =
## Opens a file named `filename` with given `mode`.
##
## Default mode is readonly. Returns true if the file could be opened.
@@ -747,7 +747,7 @@ proc open*(f: var File, filename: string,
result = false
proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
tags: [], benign.} =
tags: [], gcsafe.} =
## Reopens the file `f` with given `filename` and `mode`. This
## is often used to redirect the `stdin`, `stdout` or `stderr`
## file variables.
@@ -766,7 +766,7 @@ proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
result = false
proc open*(f: var File, filehandle: FileHandle,
mode: FileMode = fmRead): bool {.tags: [], raises: [], benign.} =
mode: FileMode = fmRead): bool {.tags: [], raises: [], gcsafe.} =
## Creates a `File` from a `filehandle` with given `mode`.
##
## Default mode is readonly. Returns true if the file could be opened.
@@ -792,26 +792,26 @@ proc open*(filename: string,
if not open(result, filename, mode, bufSize):
raise newException(IOError, "cannot open: " & filename)
proc setFilePos*(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) {.benign, sideEffect.} =
proc setFilePos*(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) {.gcsafe, sideEffect.} =
## Sets the position of the file pointer that is used for read/write
## operations. The file's first byte has the index zero.
if c_fseek(f, pos, cint(relativeTo)) != 0:
raiseEIO("cannot set file position")
proc getFilePos*(f: File): int64 {.benign.} =
proc getFilePos*(f: File): int64 {.gcsafe.} =
## 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.
result = c_ftell(f)
if result < 0: raiseEIO("cannot retrieve file position")
proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.} =
proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], gcsafe.} =
## Retrieves the file size (in bytes) of `f`.
let oldPos = getFilePos(f)
discard c_fseek(f, 0, 2) # seek the end of the file
result = getFilePos(f)
setFilePos(f, oldPos)
proc setStdIoUnbuffered*() {.tags: [], benign.} =
proc setStdIoUnbuffered*() {.tags: [], gcsafe.} =
## Configures `stdin`, `stdout` and `stderr` to be unbuffered.
when declared(stdout):
discard c_setvbuf(stdout, nil, IONBF, 0)
@@ -865,7 +865,7 @@ when defined(windows) and appType == "console" and
discard setConsoleCP(Utf8codepage)
addExitProc(restoreConsoleCP)
proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.} =
proc readFile*(filename: string): string {.tags: [ReadIOEffect], gcsafe.} =
## Opens a file named `filename` for reading, calls `readAll
## <#readAll,File>`_ and closes the file afterwards. Returns the string.
## Raises an IO exception in case of an error. If you need to call
@@ -880,7 +880,7 @@ proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.} =
else:
raise newException(IOError, "cannot open: " & filename)
proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.} =
proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], gcsafe.} =
## Opens a file named `filename` for writing. Then writes the
## `content` completely to the file and closes the file afterwards.
## Raises an IO exception in case of an error.

View File

@@ -1150,7 +1150,7 @@ template sysAssert(cond: bool, msg: string) =
const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
when notJSnotNims and hasAlloc and not defined(nimSeqsV2):
proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}
proc addChar(s: NimString, c: char): NimString {.compilerproc, gcsafe.}
when defined(nimscript) or not defined(nimSeqsV2):
proc add*[T](x: var seq[T], y: sink T) {.magic: "AppendSeqElem", noSideEffect.}
@@ -1632,7 +1632,7 @@ when not defined(js) and hasThreadSupport and hostOS != "standalone":
when not defined(js) and defined(nimV2):
type
DestructorProc = proc (p: pointer) {.nimcall, benign, raises: [].}
DestructorProc = proc (p: pointer) {.nimcall, gcsafe, raises: [].}
TNimTypeV2 {.compilerproc.} = object
destructor: pointer
size: int
@@ -1740,7 +1740,7 @@ when not defined(nimscript):
when not declared(sysFatal):
include "system/fatal"
proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", benign, sideEffect.}
proc echo*(x: varargs[typed, `$`]) {.magic: "Echo", gcsafe, sideEffect.}
## Writes and flushes the parameters to the standard output.
##
## Special built-in that takes a variable number of arguments. Each argument
@@ -1847,7 +1847,7 @@ when notJSnotNims:
## lead to the `raise` statement. This only works for debug builds.
var
globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}
globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, gcsafe.}
## With this hook you can influence exception handling on a global level.
## If not nil, every 'raise' statement ends up calling this hook.
##
@@ -1856,7 +1856,7 @@ when notJSnotNims:
## If `globalRaiseHook` returns false, the exception is caught and does
## not propagate further through the call stack.
localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}
localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, gcsafe.}
## With this hook you can influence exception handling on a
## thread local level.
## If not nil, every 'raise' statement ends up calling this hook.
@@ -1866,7 +1866,7 @@ when notJSnotNims:
## If `localRaiseHook` returns false, the exception
## is caught and does not propagate further through the call stack.
outOfMemHook*: proc () {.nimcall, tags: [], benign, raises: [].}
outOfMemHook*: proc () {.nimcall, tags: [], gcsafe, raises: [].}
## Set this variable to provide a procedure that should be called
## in case of an `out of memory`:idx: event. The standard handler
## writes an error message and terminates the program.
@@ -1887,7 +1887,7 @@ when notJSnotNims:
## If the handler does not raise an exception, ordinary control flow
## continues and the program is terminated.
unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], benign, raises: [].}
unhandledExceptionHook*: proc (e: ref Exception) {.nimcall, tags: [], gcsafe, raises: [].}
## Set this variable to provide a procedure that should be called
## in case of an `unhandle exception` event. The standard handler
## writes an error message and terminates the program, except when
@@ -2030,7 +2030,7 @@ when hostOS == "standalone" and defined(nogc):
if s == nil or s.len == 0: result = cstring""
else: result = cast[cstring](addr s.data)
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.}
## Get type information for `x`.
##
## Ordinary code should not use this, but the `typeinfo module

View File

@@ -725,7 +725,7 @@ proc getSmallChunk(a: var MemRegion): PSmallChunk =
# -----------------------------------------------------------------------------
when not defined(gcDestructors):
proc isAllocatedPtr(a: MemRegion, p: pointer): bool {.benign.}
proc isAllocatedPtr(a: MemRegion, p: pointer): bool {.gcsafe.}
when true:
template allocInv(a: MemRegion): bool = true

View File

@@ -9,11 +9,11 @@
include seqs_v2_reimpl
proc genericResetAux(dest: pointer, n: ptr TNimNode) {.benign.}
proc genericResetAux(dest: pointer, n: ptr TNimNode) {.gcsafe.}
proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.benign.}
proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.gcsafe.}
proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
shallow: bool) {.benign.} =
shallow: bool) {.gcsafe.} =
var
d = cast[int](dest)
s = cast[int](src)
@@ -187,8 +187,8 @@ proc genericAssignOpenArray(dest, src: pointer, len: int,
genericAssign(cast[pointer](d +% i *% mt.base.size),
cast[pointer](s +% i *% mt.base.size), mt.base)
proc objectInit(dest: pointer, typ: PNimType) {.compilerproc, benign.}
proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} =
proc objectInit(dest: pointer, typ: PNimType) {.compilerproc, gcsafe.}
proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} =
var d = cast[int](dest)
case n.kind
of nkNone: sysAssert(false, "objectInitAux")
@@ -224,7 +224,7 @@ proc objectInit(dest: pointer, typ: PNimType) =
# ---------------------- assign zero -----------------------------------------
proc genericReset(dest: pointer, mt: PNimType) {.compilerproc, benign.}
proc genericReset(dest: pointer, mt: PNimType) {.compilerproc, gcsafe.}
proc genericResetAux(dest: pointer, n: ptr TNimNode) =
var d = cast[int](dest)
case n.kind

View File

@@ -51,7 +51,7 @@ proc split(t: var PAvlNode) =
t.link[0] = temp
inc t.level
proc add(a: var MemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
proc add(a: var MemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} =
if t.isBottom:
t = allocAvlNode(a, key, upperBound)
else:
@@ -70,7 +70,7 @@ proc add(a: var MemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
skew(t)
split(t)
proc del(a: var MemRegion, t: var PAvlNode, x: int) {.benign.} =
proc del(a: var MemRegion, t: var PAvlNode, x: int) {.gcsafe.} =
if isBottom(t): return
a.last = t
if x <% t.key:

View File

@@ -181,10 +181,10 @@ proc deinitRawChannel(p: pointer) =
when not usesDestructors:
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
mode: LoadStoreMode) {.benign.}
mode: LoadStoreMode) {.gcsafe.}
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
mode: LoadStoreMode) {.benign.} =
mode: LoadStoreMode) {.gcsafe.} =
var
d = cast[int](dest)
s = cast[int](src)

View File

@@ -62,8 +62,8 @@ const
colorMask = 0b011
type
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
TraceProc = proc (p, env: pointer) {.nimcall, gcsafe, raises: [].}
DisposeProc = proc (p: pointer) {.nimcall, gcsafe, raises: [].}
template color(c): untyped = c.rc and colorMask
template setColor(c, col) =

View File

@@ -58,9 +58,9 @@ proc put(t: var PtrTable; key, val: pointer) =
inc t.counter
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType;
tab: var PtrTable) {.benign.}
tab: var PtrTable) {.gcsafe.}
proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode;
tab: var PtrTable) {.benign.} =
tab: var PtrTable) {.gcsafe.} =
var
d = cast[int](dest)
s = cast[int](src)

View File

@@ -16,7 +16,7 @@ import stacktraces
const noStacktraceAvailable = "No stack traceback available\n"
var
errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], benign,
errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], gcsafe,
nimcall, raises: [].})
## Function that will be called
## instead of `stdmsg.write` when printing stacktrace.
@@ -65,10 +65,10 @@ proc showErrorMessage2(data: string) {.inline.} =
# TODO showErrorMessage will turn it back to a string when a hook is set (!)
showErrorMessage(data.cstring, data.len)
proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.}
proc chckNil(p: pointer) {.noinline, compilerproc, benign.}
proc chckIndx(i, a, b: int): int {.inline, compilerproc, gcsafe.}
proc chckRange(i, a, b: int): int {.inline, compilerproc, gcsafe.}
proc chckRangeF(x, a, b: float): float {.inline, compilerproc, gcsafe.}
proc chckNil(p: pointer) {.noinline, compilerproc, gcsafe.}
type
GcFrame = ptr GcFrameHeader
@@ -657,7 +657,7 @@ when defined(cpp) and appType != "lib" and not gotoBasedExceptions and
rawQuit 1
when not defined(noSignalHandler) and not defined(useNimRtl):
type Sighandler = proc (a: cint) {.noconv, benign.}
type Sighandler = proc (a: cint) {.noconv, gcsafe.}
# xxx factor with ansi_c.CSighandlerT, posix.Sighandler
proc signalHandler(sign: cint) {.exportc: "signalHandler", noconv, raises: [].} =

View File

@@ -76,7 +76,7 @@ const
when withRealTime and not declared(getTicks):
include "system/timers"
when defined(memProfiler):
proc nimProfile(requestedSize: int) {.benign.}
proc nimProfile(requestedSize: int) {.gcsafe.}
when hasThreadSupport:
import std/sharedlist
@@ -97,7 +97,7 @@ type
waZctDecRef, waPush
#, waDebug
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign, raises: [], gcsafe.}
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe, raises: [].}
# A ref type can have a finalizer that is called before the object's
# storage is freed.
@@ -222,11 +222,11 @@ template gcTrace(cell, state: untyped) =
when traceGC: traceCell(cell, state)
# forward declarations:
proc collectCT(gch: var GcHeap) {.benign, raises: [].}
proc isOnStack(p: pointer): bool {.noinline, benign, raises: [].}
proc forAllChildren(cell: PCell, op: WalkOp) {.benign, raises: [].}
proc doOperation(p: pointer, op: WalkOp) {.benign, raises: [].}
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign, raises: [].}
proc collectCT(gch: var GcHeap) {.gcsafe, raises: [].}
proc isOnStack(p: pointer): bool {.noinline, gcsafe, raises: [].}
proc forAllChildren(cell: PCell, op: WalkOp) {.gcsafe, raises: [].}
proc doOperation(p: pointer, op: WalkOp) {.gcsafe, raises: [].}
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.gcsafe, raises: [].}
# we need the prototype here for debugging purposes
proc incRef(c: PCell) {.inline.} =
@@ -338,7 +338,7 @@ proc cellsetReset(s: var CellSet) =
{.push stacktrace:off.}
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.gcsafe.} =
var d = cast[int](dest)
case n.kind
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
@@ -687,7 +687,7 @@ proc doOperation(p: pointer, op: WalkOp) =
proc nimGCvisit(d: pointer, op: int) {.compilerRtl, raises: [].} =
doOperation(d, WalkOp(op))
proc collectZCT(gch: var GcHeap): bool {.benign, raises: [].}
proc collectZCT(gch: var GcHeap): bool {.gcsafe, raises: [].}
proc collectCycles(gch: var GcHeap) {.raises: [].} =
when hasThreadSupport:

View File

@@ -457,7 +457,7 @@ proc deallocHeap*(runFinalizers = true; allowGcAfterwards = true) =
initGC()
type
GlobalMarkerProc = proc () {.nimcall, benign, raises: [].}
GlobalMarkerProc = proc () {.nimcall, gcsafe, raises: [].}
var
globalMarkersLen {.exportc.}: int
globalMarkers {.exportc.}: array[0..3499, GlobalMarkerProc]

View File

@@ -11,7 +11,7 @@
## collectors etc.
type
GlobalMarkerProc = proc () {.nimcall, benign, raises: [], tags: [].}
GlobalMarkerProc = proc () {.nimcall, gcsafe, raises: [], tags: [].}
var
globalMarkersLen: int
globalMarkers: array[0..3499, GlobalMarkerProc]

View File

@@ -12,7 +12,7 @@ when hasAlloc:
gcOptimizeSpace ## optimize for memory footprint
when hasAlloc and not defined(js) and not usesDestructors:
proc GC_disable*() {.rtl, inl, benign, raises: [].}
proc GC_disable*() {.rtl, inl, gcsafe, raises: [].}
## Disables the GC. If called `n` times, `n` calls to `GC_enable`
## are needed to reactivate the GC.
##
@@ -20,39 +20,39 @@ when hasAlloc and not defined(js) and not usesDestructors:
## the mark and sweep phase with
## `GC_disableMarkAndSweep <#GC_disableMarkAndSweep>`_.
proc GC_enable*() {.rtl, inl, benign, raises: [].}
proc GC_enable*() {.rtl, inl, gcsafe, raises: [].}
## Enables the GC again.
proc GC_fullCollect*() {.rtl, benign, raises: [].}
proc GC_fullCollect*() {.rtl, gcsafe, raises: [].}
## Forces a full garbage collection pass.
## Ordinary code does not need to call this (and should not).
proc GC_enableMarkAndSweep*() {.rtl, benign, raises: [].}
proc GC_disableMarkAndSweep*() {.rtl, benign, raises: [].}
proc GC_enableMarkAndSweep*() {.rtl, gcsafe, raises: [].}
proc GC_disableMarkAndSweep*() {.rtl, gcsafe, raises: [].}
## The current implementation uses a reference counting garbage collector
## 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
## does not create cycles. Thus the mark and sweep phase can be deactivated
## and activated separately from the rest of the GC.
proc GC_getStatistics*(): string {.rtl, benign, raises: [].}
proc GC_getStatistics*(): string {.rtl, gcsafe, raises: [].}
## Returns an informative string about the GC's activity. This may be useful
## for tweaking.
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign, raises: [].}
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign, raises: [].}
proc GC_ref*(x: string) {.magic: "GCref", benign, raises: [].}
proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe, raises: [].}
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe, raises: [].}
proc GC_ref*(x: string) {.magic: "GCref", gcsafe, raises: [].}
## 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`,
## n calls to `GC_unref` are needed to unmark `x`.
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign, raises: [].}
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign, raises: [].}
proc GC_unref*(x: string) {.magic: "GCunref", benign, raises: [].}
proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe, raises: [].}
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe, raises: [].}
proc GC_unref*(x: string) {.magic: "GCunref", gcsafe, raises: [].}
## See the documentation of `GC_ref <#GC_ref,string>`_.
proc nimGC_setStackBottom*(theStackBottom: pointer) {.compilerRtl, noinline, benign, raises: [].}
proc nimGC_setStackBottom*(theStackBottom: pointer) {.compilerRtl, noinline, gcsafe, raises: [].}
## Expands operating GC stack range to `theStackBottom`. Does nothing
## if current stack bottom is already lower than `theStackBottom`.

View File

@@ -36,7 +36,7 @@ type
# local
waMarkPrecise # fast precise marking
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign, raises: [], gcsafe.}
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe, raises: [].}
# A ref type can have a finalizer that is called before the object's
# storage is freed.
@@ -115,10 +115,10 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
{.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
# forward declarations:
proc collectCT(gch: var GcHeap; size: int) {.benign, raises: [].}
proc forAllChildren(cell: PCell, op: WalkOp) {.benign, raises: [].}
proc doOperation(p: pointer, op: WalkOp) {.benign, raises: [].}
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign, raises: [].}
proc collectCT(gch: var GcHeap; size: int) {.gcsafe, raises: [].}
proc forAllChildren(cell: PCell, op: WalkOp) {.gcsafe, raises: [].}
proc doOperation(p: pointer, op: WalkOp) {.gcsafe, raises: [].}
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.gcsafe, raises: [].}
# we need the prototype here for debugging purposes
when defined(nimGcRefLeak):
@@ -216,7 +216,7 @@ proc initGC() =
gch.gcThreadId = atomicInc(gHeapidGenerator) - 1
gcAssert(gch.gcThreadId >= 0, "invalid computed thread ID")
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.gcsafe.} =
var d = cast[int](dest)
case n.kind
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)

View File

@@ -12,7 +12,7 @@
import std/private/syslocks
when defined(memProfiler):
proc nimProfile(requestedSize: int) {.benign.}
proc nimProfile(requestedSize: int) {.gcsafe.}
when defined(useMalloc):
proc roundup(x, v: int): int {.inline.} =
@@ -41,7 +41,7 @@ else:
# We also support 'finalizers'.
type
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign, raises: [], gcsafe.}
Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe, raises: [].}
# A ref type can have a finalizer that is called before the object's
# storage is freed.

View File

@@ -96,8 +96,8 @@ type
base*: ptr TNimType
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
finalizer*: pointer # the finalizer for the type
marker*: proc (p: pointer, op: int) {.nimcall, benign, tags: [], raises: [].} # marker proc for GC
deepcopy: proc (p: pointer): pointer {.nimcall, benign, tags: [], raises: [].}
marker*: proc (p: pointer, op: int) {.nimcall, gcsafe, tags: [], raises: [].} # marker proc for GC
deepcopy: proc (p: pointer): pointer {.nimcall, gcsafe, tags: [], raises: [].}
when defined(nimSeqsV2):
typeInfoV2*: pointer
when defined(nimTypeNames):

View File

@@ -51,7 +51,7 @@ proc nimCharToStr(x: char): string {.compilerproc.} =
proc isNimException(): bool {.asmNoStackFrame.} =
{.emit: "return `lastJSError` && `lastJSError`.m_type;".}
proc getCurrentException*(): ref Exception {.compilerRtl, benign.} =
proc getCurrentException*(): ref Exception {.compilerRtl, gcsafe.} =
if isNimException(): result = cast[ref Exception](lastJSError)
proc getCurrentExceptionMsg*(): string =
@@ -72,7 +72,7 @@ proc getCurrentExceptionMsg*(): string =
proc setCurrentException*(exc: ref Exception) =
lastJSError = cast[PJSError](exc)
proc closureIterSetExc(e: ref Exception) {.compilerRtl, benign.} =
proc closureIterSetExc(e: ref Exception) {.compilerRtl, gcsafe.} =
setCurrentException(e)
proc pushCurrentException(e: sink(ref Exception)) {.compilerRtl, inline.} =

View File

@@ -6,7 +6,7 @@ when notJSnotNims:
## Exactly `size` bytes will be overwritten. Like any procedure
## dealing with raw memory this is **unsafe**.
proc copyMem*(dest, source: pointer, size: Natural) {.inline, benign,
proc copyMem*(dest, source: pointer, size: Natural) {.inline, gcsafe,
tags: [], raises: [], enforceNoRaises.}
## Copies the contents from the memory at `source` to the memory
## at `dest`.
@@ -14,7 +14,7 @@ when notJSnotNims:
## regions may not overlap. Like any procedure dealing with raw
## memory this is **unsafe**.
proc moveMem*(dest, source: pointer, size: Natural) {.inline, benign,
proc moveMem*(dest, source: pointer, size: Natural) {.inline, gcsafe,
tags: [], raises: [], enforceNoRaises.}
## Copies the contents from the memory at `source` to the memory
## at `dest`.
@@ -48,17 +48,17 @@ when notJSnotNims:
when hasAlloc and not defined(js):
proc allocImpl*(size: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc alloc0Impl*(size: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc deallocImpl*(p: pointer) {.noconv, rtl, tags: [], benign, raises: [].}
proc reallocImpl*(p: pointer, newSize: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc realloc0Impl*(p: pointer, oldSize, newSize: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc allocImpl*(size: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc alloc0Impl*(size: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc deallocImpl*(p: pointer) {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc reallocImpl*(p: pointer, newSize: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc realloc0Impl*(p: pointer, oldSize, newSize: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc allocSharedImpl*(size: Natural): pointer {.noconv, compilerproc, rtl, benign, raises: [], tags: [].}
proc allocShared0Impl*(size: Natural): pointer {.noconv, rtl, benign, raises: [], tags: [].}
proc deallocSharedImpl*(p: pointer) {.noconv, rtl, benign, raises: [], tags: [].}
proc reallocSharedImpl*(p: pointer, newSize: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc reallocShared0Impl*(p: pointer, oldSize, newSize: Natural): pointer {.noconv, rtl, tags: [], benign, raises: [].}
proc allocSharedImpl*(size: Natural): pointer {.noconv, compilerproc, rtl, gcsafe, raises: [], tags: [].}
proc allocShared0Impl*(size: Natural): pointer {.noconv, rtl, gcsafe, raises: [], tags: [].}
proc deallocSharedImpl*(p: pointer) {.noconv, rtl, gcsafe, raises: [], tags: [].}
proc reallocSharedImpl*(p: pointer, newSize: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
proc reallocShared0Impl*(p: pointer, oldSize, newSize: Natural): pointer {.noconv, rtl, tags: [], gcsafe, raises: [].}
# Allocator statistics for memory leak tests
@@ -103,7 +103,7 @@ when hasAlloc and not defined(js):
incStat(allocCount)
allocImpl(size)
proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, benign, raises: [].} =
proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe, raises: [].} =
## Allocates a new memory block with at least `T.sizeof * size` bytes.
##
## The block has to be freed with `resize(block, 0) <#resize,ptr.T,Natural>`_
@@ -131,7 +131,7 @@ when hasAlloc and not defined(js):
incStat(allocCount)
alloc0Impl(size)
proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, benign, raises: [].} =
proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe, raises: [].} =
## Allocates a new memory block with at least `T.sizeof * size` bytes.
##
## The block has to be freed with `resize(block, 0) <#resize,ptr.T,Natural>`_
@@ -174,7 +174,7 @@ when hasAlloc and not defined(js):
## from a shared heap.
realloc0Impl(p, oldSize, newSize)
proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, benign, raises: [].} =
proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, gcsafe, raises: [].} =
## Grows or shrinks a given memory block.
##
## If `p` is **nil** then a new memory block is returned.
@@ -187,7 +187,7 @@ when hasAlloc and not defined(js):
## from a shared heap.
cast[ptr T](realloc(p, T.sizeof * newSize))
proc dealloc*(p: pointer) {.noconv, compilerproc, rtl, benign, raises: [], tags: [].} =
proc dealloc*(p: pointer) {.noconv, compilerproc, rtl, gcsafe, raises: [], tags: [].} =
## Frees the memory allocated with `alloc`, `alloc0`,
## `realloc`, `create` or `createU`.
##
@@ -218,7 +218,7 @@ when hasAlloc and not defined(js):
allocSharedImpl(size)
proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline, tags: [],
benign, raises: [].} =
gcsafe, raises: [].} =
## Allocates a new memory block on the shared heap with at
## least `T.sizeof * size` bytes.
##
@@ -296,7 +296,7 @@ when hasAlloc and not defined(js):
## `freeShared <#freeShared,ptr.T>`_.
cast[ptr T](reallocShared(p, T.sizeof * newSize))
proc deallocShared*(p: pointer) {.noconv, compilerproc, rtl, benign, raises: [], tags: [].} =
proc deallocShared*(p: pointer) {.noconv, compilerproc, rtl, gcsafe, raises: [], tags: [].} =
## Frees the memory allocated with `allocShared`, `allocShared0` or
## `reallocShared`.
##
@@ -307,7 +307,7 @@ when hasAlloc and not defined(js):
incStat(deallocCount)
deallocSharedImpl(p)
proc freeShared*[T](p: ptr T) {.inline, benign, raises: [].} =
proc freeShared*[T](p: ptr T) {.inline, gcsafe, raises: [].} =
## Frees the memory allocated with `createShared`, `createSharedU` or
## `resizeShared`.
##

View File

@@ -29,8 +29,8 @@ const
logOrc = defined(nimArcIds)
type
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
TraceProc = proc (p, env: pointer) {.nimcall, gcsafe, raises: [].}
DisposeProc = proc (p: pointer) {.nimcall, gcsafe, raises: [].}
template color(c): untyped = c.rc and colorMask
template setColor(c, col) =

View File

@@ -77,7 +77,7 @@ include system/repr_impl
type
PByteArray = ptr UncheckedArray[byte] # array[0xffff, byte]
proc addSetElem(result: var string, elem: int, typ: PNimType) {.benign.} =
proc addSetElem(result: var string, elem: int, typ: PNimType) {.gcsafe.} =
case typ.kind
of tyEnum: add result, reprEnum(elem, typ)
of tyBool: add result, reprBool(bool(elem))
@@ -147,7 +147,7 @@ when not defined(useNimRtl):
for i in 0..cl.indent-1: add result, ' '
proc reprAux(result: var string, p: pointer, typ: PNimType,
cl: var ReprClosure) {.benign.}
cl: var ReprClosure) {.gcsafe.}
proc reprArray(result: var string, p: pointer, typ: PNimType,
cl: var ReprClosure) =
@@ -188,7 +188,7 @@ when not defined(useNimRtl):
add result, "]"
proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
cl: var ReprClosure) {.benign.} =
cl: var ReprClosure) {.gcsafe.} =
case n.kind
of nkNone: sysAssert(false, "reprRecordAux")
of nkSlot: