make at least bootstrapping work
This commit is contained in:
commit
7ac6462cbd
25 changed files with 1314 additions and 425 deletions
|
|
@ -382,16 +382,24 @@ type
|
|||
|
||||
{.deprecated: [TBindSymRule: BindSymRule].}
|
||||
|
||||
proc bindSym*(ident: static[string], rule: BindSymRule = brClosed): NimNode {.
|
||||
proc bindSym*(ident: string | NimNode, rule: BindSymRule = brClosed): NimNode {.
|
||||
magic: "NBindSym", noSideEffect.}
|
||||
## creates a node that binds `ident` to a symbol node. The bound symbol
|
||||
## may be an overloaded symbol.
|
||||
## if `ident` is a NimNode, it must have nkIdent kind.
|
||||
## If ``rule == brClosed`` either an ``nkClosedSymChoice`` tree is
|
||||
## returned or ``nkSym`` if the symbol is not ambiguous.
|
||||
## If ``rule == brOpen`` either an ``nkOpenSymChoice`` tree is
|
||||
## returned or ``nkSym`` if the symbol is not ambiguous.
|
||||
## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
|
||||
## returned even if the symbol is not ambiguous.
|
||||
##
|
||||
## experimental feature:
|
||||
## use {.experimental: "dynamicBindSym".} to activate it
|
||||
## if called from template / regular code, `ident` and `rule` must be
|
||||
## constant expression / literal value.
|
||||
## if called from macros / compile time procs / static blocks,
|
||||
## `ident` and `rule` can be VM computed value.
|
||||
|
||||
proc genSym*(kind: NimSymKind = nskLet; ident = ""): NimNode {.
|
||||
magic: "NGenSym", noSideEffect.}
|
||||
|
|
@ -425,6 +433,7 @@ proc getColumn(arg: NimNode): int {.magic: "NLineInfo", noSideEffect.}
|
|||
proc getFile(arg: NimNode): string {.magic: "NLineInfo", noSideEffect.}
|
||||
|
||||
proc lineInfoObj*(n: NimNode): LineInfo {.compileTime.} =
|
||||
## returns ``LineInfo`` of ``n``, using absolute path for ``filename``
|
||||
result.filename = n.getFile
|
||||
result.line = n.getLine
|
||||
result.column = n.getColumn
|
||||
|
|
@ -1284,7 +1293,7 @@ proc customPragmaNode(n: NimNode): NimNode =
|
|||
let
|
||||
typ = n.getTypeInst()
|
||||
|
||||
if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
|
||||
if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
|
||||
return typ[1][1]
|
||||
elif typ.typeKind == ntyTypeDesc:
|
||||
let impl = typ[1].getImpl()
|
||||
|
|
@ -1319,6 +1328,8 @@ proc customPragmaNode(n: NimNode): NimNode =
|
|||
if identDefs.kind == nnkRecCase:
|
||||
identDefsStack.add(identDefs[0])
|
||||
for i in 1..<identDefs.len:
|
||||
# if it is and empty branch, skip
|
||||
if identDefs[i][0].kind == nnkNilLit: continue
|
||||
if identDefs[i][1].kind == nnkIdentDefs:
|
||||
identDefsStack.add(identDefs[i][1])
|
||||
else: # nnkRecList
|
||||
|
|
|
|||
|
|
@ -449,10 +449,11 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string =
|
|||
desc = if not symbols[j].linkDesc.isNil: symbols[j].linkDesc else: ""
|
||||
if desc.len > 0:
|
||||
result.addf("""<li><a class="reference external"
|
||||
title="$3" href="$1">$2</a></li>
|
||||
title="$3" data-doc-search-tag="$2" href="$1">$2</a></li>
|
||||
""", [url, text, desc])
|
||||
else:
|
||||
result.addf("""<li><a class="reference external" href="$1">$2</a></li>
|
||||
result.addf("""<li><a class="reference external"
|
||||
data-doc-search-tag="$2" href="$1">$2</a></li>
|
||||
""", [url, text])
|
||||
inc j
|
||||
result.add("</ul></dd>\n")
|
||||
|
|
@ -493,6 +494,7 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string =
|
|||
# Build a list of levels and extracted titles to make processing easier.
|
||||
var
|
||||
titleRef: string
|
||||
titleTag: string
|
||||
levels: seq[tuple[level: int, text: string]]
|
||||
L = 0
|
||||
level = 1
|
||||
|
|
@ -519,10 +521,12 @@ proc generateDocumentationTOC(entries: seq[IndexEntry]): string =
|
|||
let link = entries[L].link
|
||||
if link.isDocumentationTitle:
|
||||
titleRef = link
|
||||
titleTag = levels[L].text
|
||||
else:
|
||||
result.add(level.indentToLevel(levels[L].level))
|
||||
result.add("<li><a href=\"" & link & "\">" &
|
||||
levels[L].text & "</a></li>\n")
|
||||
result.addf("""<li><a class="reference" data-doc-search-tag="$1" href="$2">
|
||||
$3</a></li>
|
||||
""", [titleTag & " : " & levels[L].text, link, levels[L].text])
|
||||
inc L
|
||||
result.add(level.indentToLevel(1) & "</ul>\n")
|
||||
assert(not titleRef.isNil,
|
||||
|
|
|
|||
|
|
@ -854,20 +854,20 @@ when isMainModule:
|
|||
doAssert numbers.distribute(6)[0] == @[1, 2]
|
||||
doAssert numbers.distribute(6)[5] == @[7]
|
||||
let a = @[1, 2, 3, 4, 5, 6, 7]
|
||||
doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]]
|
||||
doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]]
|
||||
doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]]
|
||||
doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]]
|
||||
doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]]
|
||||
doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]]
|
||||
doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
|
||||
doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
|
||||
doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]]
|
||||
doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]]
|
||||
doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]]
|
||||
doAssert a.distribute(6, false) == @[
|
||||
doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]]
|
||||
doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]]
|
||||
doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]]
|
||||
doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]]
|
||||
doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]]
|
||||
doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]]
|
||||
doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
|
||||
doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
|
||||
doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]]
|
||||
doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]]
|
||||
doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]]
|
||||
doAssert a.distribute(6, false) == @[
|
||||
@[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]]
|
||||
doAssert a.distribute(8, false) == a.distribute(8, true)
|
||||
doAssert a.distribute(8, false) == a.distribute(8, true)
|
||||
doAssert a.distribute(90, false) == a.distribute(90, true)
|
||||
var b = @[0]
|
||||
for f in 1 .. 25: b.add(f)
|
||||
|
|
|
|||
|
|
@ -347,6 +347,18 @@ proc excl*[A](s: var HashSet[A], other: HashSet[A]) =
|
|||
assert other.isValid, "The set `other` needs to be initialized."
|
||||
for item in other: discard exclImpl(s, item)
|
||||
|
||||
proc pop*[A](s: var HashSet[A]): A =
|
||||
## Remove and return an arbitrary element from the set `s`.
|
||||
##
|
||||
## Raises KeyError if the set `s` is empty.
|
||||
##
|
||||
for h in 0..high(s.data):
|
||||
if isFilled(s.data[h].hcode):
|
||||
result = s.data[h].key
|
||||
excl(s, result)
|
||||
return result
|
||||
raise newException(KeyError, "set is empty")
|
||||
|
||||
proc containsOrIncl*[A](s: var HashSet[A], key: A): bool =
|
||||
## Includes `key` in the set `s` and tells if `key` was added to `s`.
|
||||
##
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ when defined(windows):
|
|||
if s.len == 0: return ""
|
||||
# educated guess of capacity:
|
||||
var cap = s.len + s.len shr 2
|
||||
result = newStringOfCap(cap*2)
|
||||
result = newString(cap*2)
|
||||
# convert to utf-16 LE
|
||||
var m = multiByteToWideChar(codePage = c.src, dwFlags = 0'i32,
|
||||
lpMultiByteStr = cstring(s),
|
||||
|
|
@ -347,7 +347,7 @@ when defined(windows):
|
|||
lpWideCharStr = nil,
|
||||
cchWideChar = cint(0))
|
||||
# and do the conversion properly:
|
||||
result = newStringOfCap(cap*2)
|
||||
result = newString(cap*2)
|
||||
m = multiByteToWideChar(codePage = c.src, dwFlags = 0'i32,
|
||||
lpMultiByteStr = cstring(s),
|
||||
cbMultiByte = cint(s.len),
|
||||
|
|
@ -364,7 +364,7 @@ when defined(windows):
|
|||
if int(c.dest) == 1200: return
|
||||
# otherwise the fun starts again:
|
||||
cap = s.len + s.len shr 2
|
||||
var res = newStringOfCap(cap)
|
||||
var res = newString(cap)
|
||||
m = wideCharToMultiByte(
|
||||
codePage = c.dest,
|
||||
dwFlags = 0'i32,
|
||||
|
|
@ -382,7 +382,7 @@ when defined(windows):
|
|||
lpMultiByteStr = nil,
|
||||
cbMultiByte = cint(0))
|
||||
# and do the conversion properly:
|
||||
res = newStringOfCap(cap)
|
||||
res = newString(cap)
|
||||
m = wideCharToMultiByte(
|
||||
codePage = c.dest,
|
||||
dwFlags = 0'i32,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ proc raiseOSError*(errorCode: OSErrorCode; additionalInfo = "") {.noinline.} =
|
|||
if additionalInfo.len == 0:
|
||||
e.msg = osErrorMsg(errorCode)
|
||||
else:
|
||||
e.msg = osErrorMsg(errorCode) & "\nAdditional info: " & additionalInfo
|
||||
e.msg = osErrorMsg(errorCode) & "\nAdditional info: '" & additionalInfo & "'"
|
||||
if e.msg == "":
|
||||
e.msg = "unknown OS error"
|
||||
raise e
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ proc newSelector*[T](): Selector[T] =
|
|||
result.maxFD = maxFD
|
||||
result.fds = newSeq[SelectorKey[T]](maxFD)
|
||||
|
||||
for i in 0 ..< maxFD:
|
||||
result.fds[i].ident = InvalidIdent
|
||||
|
||||
proc close*[T](s: Selector[T]) =
|
||||
let res = posix.close(s.epollFD)
|
||||
when hasThreadSupport:
|
||||
|
|
@ -100,12 +103,6 @@ proc close*[T](s: Selector[T]) =
|
|||
if res != 0:
|
||||
raiseIOSelectorsError(osLastError())
|
||||
|
||||
template clearKey[T](key: ptr SelectorKey[T]) =
|
||||
var empty: T
|
||||
key.ident = 0
|
||||
key.events = {}
|
||||
key.data = empty
|
||||
|
||||
proc newSelectEvent*(): SelectEvent =
|
||||
let fdci = eventfd(0, 0)
|
||||
if fdci == -1:
|
||||
|
|
@ -135,7 +132,7 @@ proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
events: set[Event], data: T) =
|
||||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0, "Descriptor $# already registered" % $fdi)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent, "Descriptor $# already registered" % $fdi)
|
||||
s.setKey(fdi, events, 0, data)
|
||||
if events != {}:
|
||||
var epv = EpollEvent(events: EPOLLRDHUP)
|
||||
|
|
@ -152,7 +149,7 @@ proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle, events: set[Event]
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor $# is not registered in the selector!" % $fdi)
|
||||
doAssert(pkey.events * maskEvents == {})
|
||||
if pkey.events != events:
|
||||
|
|
@ -180,7 +177,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor $# is not registered in the selector!" % $fdi)
|
||||
if pkey.events != {}:
|
||||
when not defined(android):
|
||||
|
|
@ -243,7 +240,7 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
|||
let fdi = int(ev.efd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0, "Event is not registered in the queue!")
|
||||
doAssert(pkey.ident != InvalidIdent, "Event is not registered in the queue!")
|
||||
doAssert(Event.User in pkey.events)
|
||||
var epv = EpollEvent()
|
||||
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0:
|
||||
|
|
@ -262,7 +259,7 @@ proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool,
|
|||
setNonBlocking(fdi.cint)
|
||||
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
var events = {Event.Timer}
|
||||
var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP)
|
||||
|
|
@ -307,7 +304,7 @@ when not defined(android):
|
|||
setNonBlocking(fdi.cint)
|
||||
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP)
|
||||
epv.data.u64 = fdi.uint
|
||||
|
|
@ -334,7 +331,7 @@ when not defined(android):
|
|||
setNonBlocking(fdi.cint)
|
||||
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP)
|
||||
epv.data.u64 = fdi.uint
|
||||
|
|
@ -347,7 +344,7 @@ when not defined(android):
|
|||
|
||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||
let fdi = int(ev.efd)
|
||||
doAssert(s.fds[fdi].ident == 0, "Event is already registered in the queue!")
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent, "Event is already registered in the queue!")
|
||||
s.setKey(fdi, {Event.User}, 0, data)
|
||||
var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP)
|
||||
epv.data.u64 = ev.efd.uint
|
||||
|
|
@ -381,7 +378,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
|
|||
let fdi = int(resTable[i].data.u64)
|
||||
let pevents = resTable[i].events
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0)
|
||||
doAssert(pkey.ident != InvalidIdent)
|
||||
var rkey = ReadyKey(fd: fdi, events: {})
|
||||
|
||||
if (pevents and EPOLLERR) != 0 or (pevents and EPOLLHUP) != 0:
|
||||
|
|
@ -482,7 +479,7 @@ template isEmpty*[T](s: Selector[T]): bool =
|
|||
(s.count == 0)
|
||||
|
||||
proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} =
|
||||
return s.fds[fd.int].ident != 0
|
||||
return s.fds[fd.int].ident != InvalidIdent
|
||||
|
||||
proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T =
|
||||
let fdi = int(fd)
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ proc newSelector*[T](): Selector[T] =
|
|||
result.fds = newSeq[SelectorKey[T]](maxFD)
|
||||
result.changes = newSeqOfCap[KEvent](MAX_KQUEUE_EVENTS)
|
||||
|
||||
for i in 0 ..< maxFD:
|
||||
result.fds[i].ident = InvalidIdent
|
||||
|
||||
result.sock = usock
|
||||
result.kqFD = kqFD
|
||||
result.maxFD = maxFD.int
|
||||
|
|
@ -128,12 +131,6 @@ proc close*[T](s: Selector[T]) =
|
|||
if res1 != 0 or res2 != 0:
|
||||
raiseIOSelectorsError(osLastError())
|
||||
|
||||
template clearKey[T](key: ptr SelectorKey[T]) =
|
||||
var empty: T
|
||||
key.ident = 0
|
||||
key.events = {}
|
||||
key.data = empty
|
||||
|
||||
proc newSelectEvent*(): SelectEvent =
|
||||
var fds: array[2, cint]
|
||||
if posix.pipe(fds) != 0:
|
||||
|
|
@ -221,7 +218,7 @@ proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
events: set[Event], data: T) =
|
||||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
s.setKey(fdi, events, 0, data)
|
||||
|
||||
if events != {}:
|
||||
|
|
@ -242,7 +239,7 @@ proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor $# is not registered in the queue!" % $fdi)
|
||||
doAssert(pkey.events * maskEvents == {})
|
||||
|
||||
|
|
@ -269,7 +266,7 @@ proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool,
|
|||
data: T): int {.discardable.} =
|
||||
let fdi = getUnique(s)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
let events = if oneshot: {Event.Timer, Event.Oneshot} else: {Event.Timer}
|
||||
let flags: cushort = if oneshot: EV_ONESHOT or EV_ADD else: EV_ADD
|
||||
|
|
@ -291,7 +288,7 @@ proc registerSignal*[T](s: Selector[T], signal: int,
|
|||
data: T): int {.discardable.} =
|
||||
let fdi = getUnique(s)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
s.setKey(fdi, {Event.Signal}, signal, data)
|
||||
var nmask, omask: Sigset
|
||||
|
|
@ -315,7 +312,7 @@ proc registerProcess*[T](s: Selector[T], pid: int,
|
|||
data: T): int {.discardable.} =
|
||||
let fdi = getUnique(s)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
|
||||
var kflags: cushort = EV_ONESHOT or EV_ADD
|
||||
setKey(s, fdi, {Event.Process, Event.Oneshot}, pid, data)
|
||||
|
|
@ -331,7 +328,7 @@ proc registerProcess*[T](s: Selector[T], pid: int,
|
|||
|
||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||
let fdi = ev.rfd.int
|
||||
doAssert(s.fds[fdi].ident == 0, "Event is already registered in the queue!")
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent, "Event is already registered in the queue!")
|
||||
setKey(s, fdi, {Event.User}, 0, data)
|
||||
|
||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
||||
|
|
@ -374,7 +371,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor [" & $fdi & "] is not registered in the queue!")
|
||||
|
||||
if pkey.events != {}:
|
||||
|
|
@ -434,7 +431,7 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
|||
let fdi = int(ev.rfd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0, "Event is not registered in the queue!")
|
||||
doAssert(pkey.ident != InvalidIdent, "Event is not registered in the queue!")
|
||||
doAssert(Event.User in pkey.events)
|
||||
modifyKQueue(s, uint(fdi), EVFILT_READ, EV_DELETE, 0, 0, nil)
|
||||
when not declared(CACHE_EVENTS):
|
||||
|
|
@ -593,7 +590,7 @@ template isEmpty*[T](s: Selector[T]): bool =
|
|||
(s.count == 0)
|
||||
|
||||
proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} =
|
||||
return s.fds[fd.int].ident != 0
|
||||
return s.fds[fd.int].ident != InvalidIdent
|
||||
|
||||
proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T =
|
||||
let fdi = int(fd)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ proc newSelector*[T](): Selector[T] =
|
|||
result.fds = newSeq[SelectorKey[T]](maxFD)
|
||||
result.pollfds = newSeq[TPollFd](maxFD)
|
||||
|
||||
for i in 0 ..< maxFD:
|
||||
result.fds[i].ident = InvalidIdent
|
||||
|
||||
proc close*[T](s: Selector[T]) =
|
||||
when hasThreadSupport:
|
||||
deinitLock(s.lock)
|
||||
|
|
@ -77,12 +80,6 @@ proc close*[T](s: Selector[T]) =
|
|||
deallocSharedArray(s.pollfds)
|
||||
deallocShared(cast[pointer](s))
|
||||
|
||||
template clearKey[T](key: ptr SelectorKey[T]) =
|
||||
var empty: T
|
||||
key.ident = 0
|
||||
key.events = {}
|
||||
key.data = empty
|
||||
|
||||
template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) =
|
||||
withPollLock(s):
|
||||
var pollev: cshort = 0
|
||||
|
|
@ -135,7 +132,7 @@ proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
events: set[Event], data: T) =
|
||||
var fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
doAssert(s.fds[fdi].ident == 0)
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent)
|
||||
setKey(s, fdi, events, 0, data)
|
||||
if events != {}: s.pollAdd(fdi.cint, events)
|
||||
|
||||
|
|
@ -146,7 +143,7 @@ proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor [" & $fdi & "] is not registered in the queue!")
|
||||
doAssert(pkey.events * maskEvents == {})
|
||||
|
||||
|
|
@ -162,7 +159,7 @@ proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle,
|
|||
|
||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||
var fdi = int(ev.rfd)
|
||||
doAssert(s.fds[fdi].ident == 0, "Event is already registered in the queue!")
|
||||
doAssert(s.fds[fdi].ident == InvalidIdent, "Event is already registered in the queue!")
|
||||
var events = {Event.User}
|
||||
setKey(s, fdi, events, 0, data)
|
||||
events.incl(Event.Read)
|
||||
|
|
@ -172,9 +169,9 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
|
|||
let fdi = int(fd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0,
|
||||
doAssert(pkey.ident != InvalidIdent,
|
||||
"Descriptor [" & $fdi & "] is not registered in the queue!")
|
||||
pkey.ident = 0
|
||||
pkey.ident = InvalidIdent
|
||||
pkey.events = {}
|
||||
s.pollRemove(fdi.cint)
|
||||
|
||||
|
|
@ -182,9 +179,9 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
|||
let fdi = int(ev.rfd)
|
||||
s.checkFd(fdi)
|
||||
var pkey = addr(s.fds[fdi])
|
||||
doAssert(pkey.ident != 0, "Event is not registered in the queue!")
|
||||
doAssert(pkey.ident != InvalidIdent, "Event is not registered in the queue!")
|
||||
doAssert(Event.User in pkey.events)
|
||||
pkey.ident = 0
|
||||
pkey.ident = InvalidIdent
|
||||
pkey.events = {}
|
||||
s.pollRemove(fdi.cint)
|
||||
|
||||
|
|
@ -270,7 +267,7 @@ template isEmpty*[T](s: Selector[T]): bool =
|
|||
(s.count == 0)
|
||||
|
||||
proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} =
|
||||
return s.fds[fd.int].ident != 0
|
||||
return s.fds[fd.int].ident != InvalidIdent
|
||||
|
||||
proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T =
|
||||
let fdi = int(fd)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@ proc newSelector*[T](): Selector[T] =
|
|||
result = Selector[T]()
|
||||
result.fds = newSeq[SelectorKey[T]](FD_SETSIZE)
|
||||
|
||||
for i in 0 ..< FD_SETSIZE:
|
||||
result.fds[i].ident = InvalidIdent
|
||||
|
||||
IOFD_ZERO(addr result.rSet)
|
||||
IOFD_ZERO(addr result.wSet)
|
||||
IOFD_ZERO(addr result.eSet)
|
||||
|
|
@ -195,7 +198,7 @@ proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event],
|
|||
var i = 0
|
||||
let fdi = int(fd)
|
||||
while i < FD_SETSIZE:
|
||||
if s.fds[i].ident == 0:
|
||||
if s.fds[i].ident == InvalidIdent:
|
||||
var pkey = addr(s.fds[i])
|
||||
pkey.ident = fdi
|
||||
pkey.events = events
|
||||
|
|
@ -221,7 +224,7 @@ proc delKey[T](s: Selector[T], fd: SocketHandle) =
|
|||
var i = 0
|
||||
while i < FD_SETSIZE:
|
||||
if s.fds[i].ident == fd.int:
|
||||
s.fds[i].ident = 0
|
||||
s.fds[i].ident = InvalidIdent
|
||||
s.fds[i].events = {}
|
||||
s.fds[i].data = empty
|
||||
break
|
||||
|
|
@ -335,7 +338,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
|
|||
var k = 0
|
||||
|
||||
while (i < FD_SETSIZE) and (k < count):
|
||||
if s.fds[i].ident != 0:
|
||||
if s.fds[i].ident != InvalidIdent:
|
||||
var flag = false
|
||||
var pkey = addr(s.fds[i])
|
||||
var rkey = ReadyKey(fd: int(pkey.ident), events: {})
|
||||
|
|
|
|||
|
|
@ -1004,6 +1004,13 @@ proc processElseBranch(recCaseNode, elseBranch, jsonNode, kindType,
|
|||
exprColonExpr.add(ifStmt)
|
||||
|
||||
proc createConstructor(typeSym, jsonNode: NimNode): NimNode {.compileTime.}
|
||||
|
||||
proc detectDistinctType(typeSym: NimNode): NimNode =
|
||||
let
|
||||
typeImpl = getTypeImpl(typeSym)
|
||||
typeInst = getTypeInst(typeSym)
|
||||
result = if typeImpl.typeKind == ntyDistinct: typeImpl else: typeInst
|
||||
|
||||
proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
|
||||
## Process a field from a ``RecList``.
|
||||
##
|
||||
|
|
@ -1022,8 +1029,8 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
|
|||
# Add the field value.
|
||||
# -> jsonNode["`field`"]
|
||||
let indexedJsonNode = createJsonIndexer(jsonNode, $field)
|
||||
exprColonExpr.add(createConstructor(getTypeInst(field), indexedJsonNode))
|
||||
|
||||
let typeNode = detectDistinctType(field)
|
||||
exprColonExpr.add(createConstructor(typeNode, indexedJsonNode))
|
||||
of nnkRecCase:
|
||||
# A "case" field that introduces a variant.
|
||||
let exprColonExpr = newNimNode(nnkExprColonExpr)
|
||||
|
|
@ -1248,7 +1255,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
|||
let seqT = typeSym[1]
|
||||
let forLoopI = genSym(nskForVar, "i")
|
||||
let indexerNode = createJsonIndexer(jsonNode, forLoopI)
|
||||
let constructorNode = createConstructor(seqT, indexerNode)
|
||||
let constructorNode = createConstructor(detectDistinctType(seqT), indexerNode)
|
||||
|
||||
# Create a statement expression containing a for loop.
|
||||
result = quote do:
|
||||
|
|
@ -1284,7 +1291,10 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
|||
|
||||
# Handle all other types.
|
||||
let obj = getType(typeSym)
|
||||
if obj.kind == nnkBracketExpr:
|
||||
let typeNode = getTypeImpl(typeSym)
|
||||
if typeNode.typeKind == ntyDistinct:
|
||||
result = createConstructor(typeNode, jsonNode)
|
||||
elif obj.kind == nnkBracketExpr:
|
||||
# When `Sym "Foo"` turns out to be a `ref object`.
|
||||
result = createConstructor(obj, jsonNode)
|
||||
else:
|
||||
|
|
@ -1295,6 +1305,21 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
|||
# TODO: The fact that `jsonNode` here works to give a good line number
|
||||
# is weird. Specifying typeSym should work but doesn't.
|
||||
error("Use a named tuple instead of: " & $toStrLit(typeSym), jsonNode)
|
||||
of nnkDistinctTy:
|
||||
var baseType = typeSym
|
||||
# solve nested distinct types
|
||||
while baseType.typeKind == ntyDistinct:
|
||||
let impl = getTypeImpl(baseType[0])
|
||||
if impl.typeKind != ntyDistinct:
|
||||
baseType = baseType[0]
|
||||
break
|
||||
baseType = impl
|
||||
let ret = createConstructor(baseType, jsonNode)
|
||||
let typeInst = getTypeInst(typeSym)
|
||||
result = quote do:
|
||||
(
|
||||
`typeInst`(`ret`)
|
||||
)
|
||||
else:
|
||||
doAssert false, "Unable to create constructor for: " & $typeSym.kind
|
||||
|
||||
|
|
@ -1418,7 +1443,7 @@ macro to*(node: JsonNode, T: typedesc): untyped =
|
|||
## doAssert data.person.age == 21
|
||||
## doAssert data.list == @[1, 2, 3, 4]
|
||||
|
||||
let typeNode = getTypeInst(T)
|
||||
let typeNode = getTypeImpl(T)
|
||||
expectKind(typeNode, nnkBracketExpr)
|
||||
doAssert(($typeNode[0]).normalize == "typedesc")
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ const mimes* = {
|
|||
"xcf": "application/x-xcf",
|
||||
"fig": "application/x-xfig",
|
||||
"xpi": "application/x-xpinstall",
|
||||
"wasm": "application/wasm",
|
||||
"amr": "audio/amr",
|
||||
"awb": "audio/amr-wb",
|
||||
"amr": "audio/amr",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
## immediately.
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## var socket = newSocket()
|
||||
## var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
## socket.sendTo("192.168.0.1", Port(27960), "status\n")
|
||||
##
|
||||
## Creating a server
|
||||
|
|
|
|||
|
|
@ -971,7 +971,7 @@ proc rawCreateDir(dir: string): bool =
|
|||
elif errno in {EEXIST, ENOSYS}:
|
||||
result = false
|
||||
else:
|
||||
raiseOSError(osLastError())
|
||||
raiseOSError(osLastError(), dir)
|
||||
elif defined(posix):
|
||||
let res = mkdir(dir, 0o777)
|
||||
if res == 0'i32:
|
||||
|
|
@ -980,7 +980,7 @@ proc rawCreateDir(dir: string): bool =
|
|||
result = false
|
||||
else:
|
||||
#echo res
|
||||
raiseOSError(osLastError())
|
||||
raiseOSError(osLastError(), dir)
|
||||
else:
|
||||
when useWinUnicode:
|
||||
wrapUnary(res, createDirectoryW, dir)
|
||||
|
|
@ -992,7 +992,7 @@ proc rawCreateDir(dir: string): bool =
|
|||
elif getLastError() == 183'i32:
|
||||
result = false
|
||||
else:
|
||||
raiseOSError(osLastError())
|
||||
raiseOSError(osLastError(), dir)
|
||||
|
||||
proc existsOrCreateDir*(dir: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [WriteDirEffect, ReadDirEffect].} =
|
||||
|
|
@ -1005,7 +1005,7 @@ proc existsOrCreateDir*(dir: string): bool {.rtl, extern: "nos$1",
|
|||
if result:
|
||||
# path already exists - need to check that it is indeed a directory
|
||||
if not existsDir(dir):
|
||||
raise newException(IOError, "Failed to create the directory")
|
||||
raise newException(IOError, "Failed to create '" & dir & "'")
|
||||
|
||||
proc createDir*(dir: string) {.rtl, extern: "nos$1",
|
||||
tags: [WriteDirEffect, ReadDirEffect].} =
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ else: # UNIX-like operating system
|
|||
DirSep* = '/'
|
||||
AltSep* = DirSep
|
||||
PathSep* = ':'
|
||||
FileSystemCaseSensitive* = true
|
||||
FileSystemCaseSensitive* = when defined(macosx): false else: true
|
||||
ExeExt* = ""
|
||||
ScriptExt* = ""
|
||||
DynlibFormat* = when defined(macosx): "lib$1.dylib" else: "lib$1.so"
|
||||
|
|
@ -410,6 +410,11 @@ proc cmpPaths*(pathA, pathB: string): int {.
|
|||
## | 0 iff pathA == pathB
|
||||
## | < 0 iff pathA < pathB
|
||||
## | > 0 iff pathA > pathB
|
||||
runnableExamples:
|
||||
when defined(macosx):
|
||||
doAssert cmpPaths("foo", "Foo") == 0
|
||||
elif defined(posix):
|
||||
doAssert cmpPaths("foo", "Foo") > 0
|
||||
if FileSystemCaseSensitive:
|
||||
result = cmp(pathA, pathB)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ proc random*[T](a: openArray[T]): T {.deprecated.} =
|
|||
## Use ``rand`` instead.
|
||||
result = a[random(a.low..a.len)]
|
||||
|
||||
proc rand*(r: var Rand; max: int): int {.benign.} =
|
||||
proc rand*(r: var Rand; max: Natural): int {.benign.} =
|
||||
## Returns a random number in the range 0..max. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
|
|
@ -128,7 +128,7 @@ proc rand*(max: int): int {.benign.} =
|
|||
## number, i.e. a tickcount.
|
||||
rand(state, max)
|
||||
|
||||
proc rand*(r: var Rand; max: float): float {.benign.} =
|
||||
proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.benign.} =
|
||||
## Returns a random number in the range 0..max. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
|
|
@ -218,4 +218,17 @@ when isMainModule:
|
|||
doAssert rand(0) == 0
|
||||
doAssert rand("a") == 'a'
|
||||
|
||||
when compileOption("rangeChecks"):
|
||||
try:
|
||||
discard rand(-1)
|
||||
doAssert false
|
||||
except RangeError:
|
||||
discard
|
||||
|
||||
try:
|
||||
discard rand(-1.0)
|
||||
doAssert false
|
||||
except RangeError:
|
||||
discard
|
||||
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -261,6 +261,9 @@ else:
|
|||
param: int
|
||||
data: T
|
||||
|
||||
const
|
||||
InvalidIdent = -1
|
||||
|
||||
proc raiseIOSelectorsError[T](message: T) =
|
||||
var msg = ""
|
||||
when T is string:
|
||||
|
|
@ -302,6 +305,12 @@ else:
|
|||
if posix.sigprocmask(SIG_UNBLOCK, newmask, oldmask) == -1:
|
||||
raiseIOSelectorsError(osLastError())
|
||||
|
||||
template clearKey[T](key: ptr SelectorKey[T]) =
|
||||
var empty: T
|
||||
key.ident = InvalidIdent
|
||||
key.events = {}
|
||||
key.data = empty
|
||||
|
||||
when defined(linux):
|
||||
include ioselects/ioselectors_epoll
|
||||
elif bsdPlatform:
|
||||
|
|
|
|||
|
|
@ -181,10 +181,27 @@ elif defined(windows):
|
|||
type
|
||||
Month* = enum ## Represents a month. Note that the enum starts at ``1``, so ``ord(month)`` will give
|
||||
## the month number in the range ``[1..12]``.
|
||||
mJan = 1, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec
|
||||
mJan = (1, "January")
|
||||
mFeb = "February"
|
||||
mMar = "March"
|
||||
mApr = "April"
|
||||
mMay = "May"
|
||||
mJun = "June"
|
||||
mJul = "July"
|
||||
mAug = "August"
|
||||
mSep = "September"
|
||||
mOct = "October"
|
||||
mNov = "November"
|
||||
mDec = "December"
|
||||
|
||||
WeekDay* = enum ## Represents a weekday.
|
||||
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
||||
dMon = "Monday"
|
||||
dTue = "Tuesday"
|
||||
dWed = "Wednesday"
|
||||
dThu = "Thursday"
|
||||
dFri = "Friday"
|
||||
dSat = "Saturday"
|
||||
dSun = "Sunday"
|
||||
|
||||
MonthdayRange* = range[1..31]
|
||||
HourRange* = range[0..23]
|
||||
|
|
@ -1074,20 +1091,6 @@ proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} =
|
|||
result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) &
|
||||
':' & intToStr(ti.second, 2)
|
||||
|
||||
proc `$`*(day: WeekDay): string =
|
||||
## Stringify operator for ``WeekDay``.
|
||||
const lookup: array[WeekDay, string] = ["Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday", "Sunday"]
|
||||
return lookup[day]
|
||||
|
||||
proc `$`*(m: Month): string =
|
||||
## Stringify operator for ``Month``.
|
||||
const lookup: array[Month, string] = ["January", "February", "March",
|
||||
"April", "May", "June", "July", "August", "September", "October",
|
||||
"November", "December"]
|
||||
return lookup[m]
|
||||
|
||||
|
||||
proc toParts* (ti: TimeInterval): TimeIntervalParts =
|
||||
## Converts a `TimeInterval` into an array consisting of its time units,
|
||||
## starting with nanoseconds and ending with years
|
||||
|
|
|
|||
|
|
@ -1479,8 +1479,8 @@ when defined(nimdoc):
|
|||
##
|
||||
## Note that this is a *runtime* call and using ``quit`` inside a macro won't
|
||||
## have any compile time effect. If you need to stop the compiler inside a
|
||||
## macro, use the `error <manual.html#error-pragma>`_ or `fatal
|
||||
## <manual.html#fatal-pragma>`_ pragmas.
|
||||
## macro, use the `error <manual.html#pragmas-error-pragma>`_ or `fatal
|
||||
## <manual.html#pragmas-fatal-pragma>`_ pragmas.
|
||||
|
||||
elif defined(genode):
|
||||
include genode/env
|
||||
|
|
@ -2438,7 +2438,7 @@ iterator fieldPairs*[T: tuple|object](x: T): RootObj {.
|
|||
## When you iterate over objects with different field types you have to use
|
||||
## the compile time ``when`` instead of a runtime ``if`` to select the code
|
||||
## you want to run for each type. To perform the comparison use the `is
|
||||
## operator <manual.html#is-operator>`_. Example:
|
||||
## operator <manual.html#generics-is-operator>`_. Example:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
##
|
||||
|
|
@ -3788,7 +3788,9 @@ template doAssert*(cond: bool, msg = "") =
|
|||
## same as `assert` but is always turned on and not affected by the
|
||||
## ``--assertions`` command line switch.
|
||||
bind instantiationInfo
|
||||
{.line: instantiationInfo().}:
|
||||
# NOTE: `true` is correct here; --excessiveStackTrace:on will control whether
|
||||
# or not to output full paths.
|
||||
{.line: instantiationInfo(-1, true).}:
|
||||
if not cond:
|
||||
raiseAssert(astToStr(cond) & ' ' &
|
||||
instantiationInfo(-1, false).fileName & '(' &
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ type
|
|||
nextChunkSize: int
|
||||
bottomData: AvlNode
|
||||
heapLinks: HeapLinks
|
||||
when defined(nimTypeNames):
|
||||
allocCounter, deallocCounter: int
|
||||
|
||||
const
|
||||
fsLookupTable: array[byte, int8] = [
|
||||
|
|
@ -434,8 +436,9 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
|
|||
a.nextChunkSize = PageSize*4
|
||||
else:
|
||||
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
|
||||
var size = size
|
||||
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize)
|
||||
|
||||
var size = size
|
||||
if size > a.nextChunkSize:
|
||||
result = cast[PBigChunk](osAllocPages(size))
|
||||
else:
|
||||
|
|
@ -737,6 +740,8 @@ when false:
|
|||
result = nil
|
||||
|
||||
proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
|
||||
when defined(nimTypeNames):
|
||||
inc(a.allocCounter)
|
||||
sysAssert(allocInv(a), "rawAlloc: begin")
|
||||
sysAssert(roundup(65, 8) == 72, "rawAlloc: roundup broken")
|
||||
sysAssert(requestedSize >= sizeof(FreeCell), "rawAlloc: requested size too small")
|
||||
|
|
@ -810,6 +815,8 @@ proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
|
|||
zeroMem(result, requestedSize)
|
||||
|
||||
proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||
when defined(nimTypeNames):
|
||||
inc(a.deallocCounter)
|
||||
#sysAssert(isAllocatedPtr(a, p), "rawDealloc: no allocated pointer")
|
||||
sysAssert(allocInv(a), "rawDealloc: begin")
|
||||
var c = pageAddr(p)
|
||||
|
|
@ -975,6 +982,10 @@ proc getOccupiedMem(a: MemRegion): int {.inline.} =
|
|||
result = a.occ
|
||||
# a.currMem - a.freeMem
|
||||
|
||||
when defined(nimTypeNames):
|
||||
proc getMemCounters(a: MemRegion): (int, int) {.inline.} =
|
||||
(a.allocCounter, a.deallocCounter)
|
||||
|
||||
# ---------------------- thread memory region -------------------------------
|
||||
|
||||
template instantiateForRegion(allocator: untyped) =
|
||||
|
|
@ -1018,6 +1029,9 @@ template instantiateForRegion(allocator: untyped) =
|
|||
proc getOccupiedMem(): int = return allocator.occ #getTotalMem() - getFreeMem()
|
||||
proc getMaxMem*(): int = return getMaxMem(allocator)
|
||||
|
||||
when defined(nimTypeNames):
|
||||
proc getMemCounters*(): (int, int) = getMemCounters(allocator)
|
||||
|
||||
# -------------------- shared heap region ----------------------------------
|
||||
when hasThreadSupport:
|
||||
var sharedHeap: MemRegion
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue