make tests green

This commit is contained in:
Araq 2014-08-31 15:15:26 +02:00
commit 30823c1ce3
44 changed files with 415 additions and 403 deletions

View file

@ -23,12 +23,14 @@ type
## in preventDeadlocks-mode guarantees re-entrancy.
TCond* = TSysCond ## Nim condition variable
FLock* = object of TEffect ## effect that denotes that some lock operation
## is performed
FAquireLock* = object of FLock ## effect that denotes that some lock is
## aquired
FReleaseLock* = object of FLock ## effect that denotes that some lock is
## released
LockEffect* = object of RootEffect ## effect that denotes that some lock operation
## is performed
AquireEffect* = object of LockEffect ## effect that denotes that some lock is
## aquired
ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is
## released
{.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect,
FReleaseLock: ReleaseEffect].}
const
noDeadlocks = defined(preventDeadlocks)
@ -58,7 +60,7 @@ proc deinitLock*(lock: var TLock) {.inline.} =
## Frees the resources associated with the lock.
deinitSys(lock)
proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} =
proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} =
## Tries to acquire the given lock. Returns `true` on success.
result = tryAcquireSys(lock)
when noDeadlocks:
@ -90,7 +92,7 @@ proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} =
inc(locksLen)
assert orderedLocks()
proc acquire*(lock: var TLock) {.tags: [FAquireLock].} =
proc acquire*(lock: var TLock) {.tags: [AquireEffect].} =
## Acquires the given lock.
when nodeadlocks:
var p = addr(lock)
@ -135,7 +137,7 @@ proc acquire*(lock: var TLock) {.tags: [FAquireLock].} =
else:
acquireSys(lock)
proc release*(lock: var TLock) {.tags: [FReleaseLock].} =
proc release*(lock: var TLock) {.tags: [ReleaseEffect].} =
## Releases the given lock.
when nodeadlocks:
var p = addr(lock)

View file

@ -74,7 +74,7 @@ proc newGenTable*[T](mode: TGenTableMode): PGenTable[T] =
proc nextTry(h, maxHash: THash): THash {.inline.} =
result = ((5 * h) + 1) and maxHash
proc RawGet[T](tbl: PGenTable[T], key: string): int =
proc rawGet[T](tbl: PGenTable[T], key: string): int =
var h: THash
h = myhash(tbl, key) and high(tbl.data) # start with real hash value
while not isNil(tbl.data[h].key):
@ -83,7 +83,7 @@ proc RawGet[T](tbl: PGenTable[T], key: string): int =
h = nextTry(h, high(tbl.data))
result = - 1
proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
key: string, val: T) =
var h: THash
h = myhash(tbl, key) and high(data)
@ -92,12 +92,12 @@ proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
data[h].key = key
data[h].val = val
proc Enlarge[T](tbl: PGenTable[T]) =
proc enlarge[T](tbl: PGenTable[T]) =
var n: TGenKeyValuePairSeq[T]
newSeq(n, len(tbl.data) * growthFactor)
for i in countup(0, high(tbl.data)):
if not isNil(tbl.data[i].key):
RawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val)
rawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val)
swap(tbl.data, n)
proc hasKey*[T](tbl: PGenTable[T], key: string): bool =
@ -108,17 +108,17 @@ proc `[]`*[T](tbl: PGenTable[T], key: string): T =
## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`,
## default(T) is returned and no exception is raised. One can check
## with ``hasKey`` whether the key exists.
var index = RawGet(tbl, key)
var index = rawGet(tbl, key)
if index >= 0: result = tbl.data[index].val
proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) =
## puts a (key, value)-pair into `tbl`.
var index = RawGet(tbl, key)
var index = rawGet(tbl, key)
if index >= 0:
tbl.data[index].val = val
else:
if mustRehash(len(tbl.data), tbl.counter): Enlarge(tbl)
RawInsert(tbl, tbl.data, key, val)
if mustRehash(len(tbl.data), tbl.counter): enlarge(tbl)
rawInsert(tbl, tbl.data, key, val)
inc(tbl.counter)

View file

@ -422,7 +422,7 @@ proc toHtmlTag(s: string): THtmlTag =
of "wbr": tagWbr
else: tagUnknown
proc htmlTag*(n: PXmlNode): THtmlTag =
proc htmlTag*(n: XmlNode): THtmlTag =
## gets `n`'s tag as a ``THtmlTag``.
if n.clientData == 0:
n.clientData = toHtmlTag(n.tag).ord
@ -438,24 +438,24 @@ proc entityToUtf8*(entity: string): string =
## converts an HTML entity name like ``Ü`` to its UTF-8 equivalent.
## "" is returned if the entity name is unknown. The HTML parser
## already converts entities to UTF-8.
for name, val in items(entities):
if name == entity: return toUTF8(TRune(val))
for name, val in items(Entities):
if name == entity: return toUTF8(Rune(val))
result = ""
proc addNode(father, son: PXmlNode) =
proc addNode(father, son: XmlNode) =
if son != nil: add(father, son)
proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode
proc parse(x: var XmlParser, errors: var seq[string]): XmlNode
proc expected(x: var TXmlParser, n: PXmlNode): string =
proc expected(x: var XmlParser, n: XmlNode): string =
result = errorMsg(x, "</" & n.tag & "> expected")
template elemName(x: expr): expr = rawData(x)
proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
proc untilElementEnd(x: var XmlParser, result: XmlNode,
errors: var seq[string]) =
# we parsed e.g. ``<br>`` and don't really expect a ``</br>``:
if result.htmlTag in singleTags:
if result.htmlTag in SingleTags:
if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0:
return
while true:
@ -496,7 +496,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
else:
result.addNode(parse(x, errors))
proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
proc parse(x: var XmlParser, errors: var seq[string]): XmlNode =
case x.kind
of xmlComment:
result = newComment(x.rawData)
@ -549,11 +549,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
next(x)
of xmlEof: discard
proc parseHtml*(s: PStream, filename: string,
errors: var seq[string]): PXmlNode =
proc parseHtml*(s: Stream, filename: string,
errors: var seq[string]): XmlNode =
## parses the XML from stream `s` and returns a ``PXmlNode``. Every
## occured parsing error is added to the `errors` sequence.
var x: TXmlParser
var x: XmlParser
open(x, s, filename, {reportComments, reportWhitespace})
next(x)
# skip the DOCTYPE:
@ -573,21 +573,21 @@ proc parseHtml*(s: PStream, filename: string,
if result.len == 1:
result = result[0]
proc parseHtml*(s: PStream): PXmlNode =
proc parseHtml*(s: Stream): XmlNode =
## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing
## errors are ignored.
var errors: seq[string] = @[]
result = parseHtml(s, "unknown_html_doc", errors)
proc loadHtml*(path: string, errors: var seq[string]): PXmlNode =
proc loadHtml*(path: string, errors: var seq[string]): XmlNode =
## Loads and parses HTML from file specified by ``path``, and returns
## a ``PXmlNode``. Every occured parsing error is added to
## the `errors` sequence.
var s = newFileStream(path, fmRead)
if s == nil: raise newException(EIO, "Unable to read file: " & path)
if s == nil: raise newException(IOError, "Unable to read file: " & path)
result = parseHtml(s, path, errors)
proc loadHtml*(path: string): PXmlNode =
proc loadHtml*(path: string): XmlNode =
## Loads and parses HTML from file specified by ``path``, and returns
## a ``PXmlNode``. All parsing errors are ignored.
var errors: seq[string] = @[]
@ -600,7 +600,7 @@ when isMainModule:
var x = loadHtml(paramStr(1), errors)
for e in items(errors): echo e
var f: TFile
var f: File
if open(f, "test.txt", fmWrite):
f.write($x)
f.close()

View file

@ -276,14 +276,14 @@ proc parseComment(my: var XmlParser) =
my.bufpos = pos
my.kind = xmlComment
proc parseWhitespace(my: var XmlParser, skip=False) =
proc parseWhitespace(my: var XmlParser, skip=false) =
var pos = my.bufpos
var buf = my.buf
while true:
case buf[pos]
of ' ', '\t':
if not skip: add(my.a, buf[pos])
Inc(pos)
inc(pos)
of '\c':
# the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.handleCR(my, pos)
@ -304,7 +304,7 @@ const
proc parseName(my: var XmlParser, dest: var string) =
var pos = my.bufpos
var buf = my.buf
if buf[pos] in nameStartChar:
if buf[pos] in NameStartChar:
while true:
add(dest, buf[pos])
inc(pos)
@ -385,11 +385,11 @@ proc parsePI(my: var XmlParser) =
inc(pos)
of '\c':
# the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.HandleCR(my, pos)
pos = lexbase.handleCR(my, pos)
buf = my.buf
add(my.b, '\L')
of '\L':
pos = lexbase.HandleLF(my, pos)
pos = lexbase.handleLF(my, pos)
buf = my.buf
add(my.b, '\L')
else:
@ -420,11 +420,11 @@ proc parseSpecial(my: var XmlParser) =
inc(pos)
add(my.a, '>')
of '\c':
pos = lexbase.HandleCR(my, pos)
pos = lexbase.handleCR(my, pos)
buf = my.buf
add(my.a, '\L')
of '\L':
pos = lexbase.HandleLF(my, pos)
pos = lexbase.handleLF(my, pos)
buf = my.buf
add(my.a, '\L')
else:
@ -441,7 +441,7 @@ proc parseTag(my: var XmlParser) =
my.kind = xmlCharData
add(my.a, '<')
return
parseWhitespace(my, skip=True)
parseWhitespace(my, skip=true)
if my.buf[my.bufpos] in NameStartChar:
# an attribute follows:
my.kind = xmlElementOpen
@ -461,7 +461,7 @@ proc parseTag(my: var XmlParser) =
proc parseEndTag(my: var XmlParser) =
inc(my.bufpos, 2)
parseName(my, my.a)
parseWhitespace(my, skip=True)
parseWhitespace(my, skip=true)
if my.buf[my.bufpos] == '>':
inc(my.bufpos)
else:
@ -477,12 +477,12 @@ proc parseAttribute(my: var XmlParser) =
if my.a.len == 0:
markError(my, errGtExpected)
return
parseWhitespace(my, skip=True)
parseWhitespace(my, skip=true)
if my.buf[my.bufpos] != '=':
markError(my, errEqExpected)
return
inc(my.bufpos)
parseWhitespace(my, skip=True)
parseWhitespace(my, skip=true)
var pos = my.bufpos
var buf = my.buf
@ -507,11 +507,11 @@ proc parseAttribute(my: var XmlParser) =
pendingSpace = true
inc(pos)
of '\c':
pos = lexbase.HandleCR(my, pos)
pos = lexbase.handleCR(my, pos)
buf = my.buf
pendingSpace = true
of '\L':
pos = lexbase.HandleLF(my, pos)
pos = lexbase.handleLF(my, pos)
buf = my.buf
pendingSpace = true
else:
@ -527,7 +527,7 @@ proc parseAttribute(my: var XmlParser) =
else:
markError(my, errQuoteExpected)
my.bufpos = pos
parseWhitespace(my, skip=True)
parseWhitespace(my, skip=true)
proc parseCharData(my: var XmlParser) =
var pos = my.bufpos
@ -537,11 +537,11 @@ proc parseCharData(my: var XmlParser) =
of '\0', '<', '&': break
of '\c':
# the specification says that CR-LF, CR are to be transformed to LF
pos = lexbase.HandleCR(my, pos)
pos = lexbase.handleCR(my, pos)
buf = my.buf
add(my.a, '\L')
of '\L':
pos = lexbase.HandleLF(my, pos)
pos = lexbase.handleLF(my, pos)
buf = my.buf
add(my.a, '\L')
else:

View file

@ -186,7 +186,7 @@ proc `&`*(a: string, b: Rope): Rope {.rtl, extern: "nroConcStrRope".} =
## the concatenation operator for ropes.
result = rope(a) & b
proc `&`*(a: openarray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} =
proc `&`*(a: openArray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} =
## the concatenation operator for an openarray of ropes.
for i in countup(0, high(a)): result = result & a[i]
@ -233,7 +233,7 @@ iterator items*(r: Rope): char =
for s in leaves(r):
for c in items(s): yield c
proc write*(f: TFile, r: Rope) {.rtl, extern: "nro$1".} =
proc write*(f: File, r: Rope) {.rtl, extern: "nro$1".} =
## writes a rope to a file.
for s in leaves(r): write(f, s)
@ -291,7 +291,7 @@ when false:
if i - 1 >= start:
add(result, substr(frmt, start, i-1))
proc `%`*(frmt: string, args: openarray[Rope]): Rope {.
proc `%`*(frmt: string, args: openArray[Rope]): Rope {.
rtl, extern: "nroFormat".} =
## `%` substitution operator for ropes. Does not support the ``$identifier``
## nor ``${identifier}`` notations.
@ -324,9 +324,9 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {.
j = j * 10 + ord(frmt[i]) - ord('0')
inc(i)
if frmt[i] == '}': inc(i)
else: raise newException(EInvalidValue, "invalid format string")
else: raise newException(ValueError, "invalid format string")
add(result, args[j-1])
else: raise newException(EInvalidValue, "invalid format string")
else: raise newException(ValueError, "invalid format string")
var start = i
while i < length:
if frmt[i] != '$': inc(i)
@ -334,15 +334,15 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {.
if i - 1 >= start:
add(result, substr(frmt, start, i - 1))
proc addf*(c: var Rope, frmt: string, args: openarray[Rope]) {.
proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {.
rtl, extern: "nro$1".} =
## shortcut for ``add(c, frmt % args)``.
add(c, frmt % args)
proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} =
proc equalsFile*(r: Rope, f: File): bool {.rtl, extern: "nro$1File".} =
## returns true if the contents of the file `f` equal `r`.
var bufSize = 1024 # reasonable start value
var buf = alloc(BufSize)
var buf = alloc(bufSize)
for s in leaves(r):
if s.len > bufSize:
bufSize = max(bufSize * 2, s.len)
@ -357,7 +357,7 @@ proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} =
proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} =
## returns true if the contents of the file `f` equal `r`. If `f` does not
## exist, false is returned.
var bin: TFile
var bin: File
result = open(bin, f)
if result:
result = equalsFile(r, bin)

View file

@ -2694,7 +2694,7 @@ elif defined(JS):
proc GC_disable() = discard
proc GC_enable() = discard
proc GC_fullCollect() = discard
proc GC_setStrategy(strategy: TGC_Strategy) = discard
proc GC_setStrategy(strategy: GC_Strategy) = discard
proc GC_enableMarkAndSweep() = discard
proc GC_disableMarkAndSweep() = discard
proc GC_getStatistics(): string = return ""
@ -2706,7 +2706,7 @@ elif defined(JS):
proc dealloc(p: pointer) = discard
proc alloc(size: int): pointer = discard
proc alloc0(size: int): pointer = discard
proc realloc(p: Pointer, newsize: int): pointer = discard
proc realloc(p: pointer, newsize: int): pointer = discard
proc allocShared(size: int): pointer = discard
proc allocShared0(size: int): pointer = discard

View file

@ -31,7 +31,7 @@ when someGcc and hasThreadSupport:
## with acquire loads
## and release stores in all threads.
TAtomType* = TNumber|pointer|ptr|char
TAtomType* = SomeNumber|pointer|ptr|char
## Type Class representing valid types for use with atomic procs
proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.

View file

@ -53,8 +53,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
mode: TLoadStoreMode) {.gcsafe.} =
var
d = cast[TAddress](dest)
s = cast[TAddress](src)
d = cast[ByteAddress](dest)
s = cast[ByteAddress](src)
case n.kind
of nkSlot: storeAux(cast[pointer](d +% n.offset),
cast[pointer](s +% n.offset), n.typ, t, mode)
@ -70,8 +70,8 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
mode: TLoadStoreMode) =
var
d = cast[TAddress](dest)
s = cast[TAddress](src)
d = cast[ByteAddress](dest)
s = cast[ByteAddress](src)
sysAssert(mt != nil, "mt == nil")
case mt.kind
of tyString:
@ -108,11 +108,11 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
else:
unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize))
var dst = cast[TAddress](cast[PPointer](dest)[])
var dst = cast[ByteAddress](cast[PPointer](dest)[])
for i in 0..seq.len-1:
storeAux(
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +%
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
GenericSeqSize),
mt.base, t, mode)
var dstseq = cast[PGenericSeq](dst)
@ -192,7 +192,7 @@ template lockChannel(q: expr, action: stmt) {.immediate.} =
template sendImpl(q: expr) {.immediate.} =
if q.mask == ChannelDeadMask:
sysFatal(EDeadThread, "cannot send message; thread died")
sysFatal(DeadThreadError, "cannot send message; thread died")
acquireSys(q.lock)
var m: TMsg
shallowCopy(m, msg)
@ -215,7 +215,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =
q.ready = false
if typ != q.elemType:
releaseSys(q.lock)
sysFatal(EInvalidValue, "cannot receive message of wrong type")
sysFatal(ValueError, "cannot receive message of wrong type")
rawRecv(q, res, typ)
proc recv*[TMsg](c: var TChannel[TMsg]): TMsg =

View file

@ -80,11 +80,11 @@ template gcAssert(cond: bool, msg: string) =
proc cellToUsr(cell: PCell): pointer {.inline.} =
# convert object (=pointer to refcount) to pointer to userdata
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell)))
proc usrToCell(usr: pointer): PCell {.inline.} =
# convert pointer to userdata to object (=pointer to refcount)
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell)))
proc canbeCycleRoot(c: PCell): bool {.inline.} =
result = ntfAcyclic notin c.typ.flags
@ -169,7 +169,7 @@ proc initGC() =
init(gch.marked)
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
var d = cast[TAddress](dest)
var d = cast[ByteAddress](dest)
case n.kind
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
of nkList:
@ -181,7 +181,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
of nkNone: sysAssert(false, "forAllSlotsAux")
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) =
var d = cast[TAddress](dest)
var d = cast[ByteAddress](dest)
if dest == nil: return # nothing to do
if ntfNoRefs notin mt.flags:
case mt.kind
@ -206,7 +206,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
of tyRef: # common case
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
of tySequence:
var d = cast[TAddress](cellToUsr(cell))
var d = cast[ByteAddress](cellToUsr(cell))
var s = cast[PGenericSeq](d)
if s != nil:
for i in 0..s.len-1:
@ -220,7 +220,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
collectCT(gch)
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
# now it is buffered in the ZCT
res.typ = typ
when leakDetector and not hasThreadSupport:
@ -280,9 +280,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(TCell))
zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)),
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
newsize-oldsize)
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
when withBitvectors: excl(gch.allocated, ol)
when reallyDealloc: rawDealloc(gch.region, ol)
else:
@ -379,7 +379,7 @@ proc markGlobals(gch: var TGcHeap) =
proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
# the addresses are not as cells on the stack, so turn them to cells:
var cell = usrToCell(p)
var c = cast[TAddress](cell)
var c = cast[ByteAddress](cell)
if c >% PageSize:
# fast check: does it look like a cell?
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
@ -404,8 +404,8 @@ when not defined(useNimRtl):
# the first init must be the one that defines the stack bottom:
if gch.stackBottom == nil: gch.stackBottom = theStackBottom
else:
var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2
var b = cast[TAddress](gch.stackBottom)
var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2
var b = cast[ByteAddress](gch.stackBottom)
#c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
when stackIncreases:
gch.stackBottom = cast[pointer](min(a, b))
@ -421,9 +421,9 @@ when defined(sparc): # For SPARC architecture.
proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer
stackTop = addr(stackTop)
var b = cast[TAddress](gch.stackBottom)
var a = cast[TAddress](stackTop)
var x = cast[TAddress](p)
var b = cast[ByteAddress](gch.stackBottom)
var a = cast[ByteAddress](stackTop)
var x = cast[ByteAddress](p)
result = a <=% x and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@ -440,7 +440,7 @@ when defined(sparc): # For SPARC architecture.
# Addresses decrease as the stack grows.
while sp <= max:
gcMark(gch, sp[])
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
sp = cast[ppointer](cast[ByteAddress](sp) +% sizeof(pointer))
elif defined(ELATE):
{.error: "stack marking code is to be written for this architecture".}
@ -452,9 +452,9 @@ elif stackIncreases:
proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer
stackTop = addr(stackTop)
var a = cast[TAddress](gch.stackBottom)
var b = cast[TAddress](stackTop)
var x = cast[TAddress](p)
var a = cast[ByteAddress](gch.stackBottom)
var b = cast[ByteAddress](stackTop)
var x = cast[ByteAddress](p)
result = a <=% x and x <=% b
var
@ -465,8 +465,8 @@ elif stackIncreases:
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var registers: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
var max = cast[TAddress](gch.stackBottom)
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
var max = cast[ByteAddress](gch.stackBottom)
var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
# otherwise sp would be below the registers structure).
while sp >=% max:
@ -480,9 +480,9 @@ else:
proc isOnStack(p: pointer): bool =
var stackTop {.volatile.}: pointer
stackTop = addr(stackTop)
var b = cast[TAddress](gch.stackBottom)
var a = cast[TAddress](stackTop)
var x = cast[TAddress](p)
var b = cast[ByteAddress](gch.stackBottom)
var a = cast[ByteAddress](stackTop)
var x = cast[ByteAddress](p)
result = a <=% x and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@ -492,8 +492,8 @@ else:
type PStackSlice = ptr array [0..7, pointer]
var registers {.noinit.}: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
var max = cast[TAddress](gch.stackBottom)
var sp = cast[TAddress](addr(registers))
var max = cast[ByteAddress](gch.stackBottom)
var sp = cast[ByteAddress](addr(registers))
# loop unrolled:
while sp <% max - 8*sizeof(pointer):
gcMark(gch, cast[PStackSlice](sp)[0])
@ -546,7 +546,7 @@ when not defined(useNimRtl):
else:
dec(gch.recGcLock)
proc GC_setStrategy(strategy: TGC_Strategy) = discard
proc GC_setStrategy(strategy: GC_Strategy) = discard
proc GC_enableMarkAndSweep() =
gch.cycleThreshold = InitialThreshold

View file

@ -18,7 +18,7 @@ type
PSafePoint = ptr TSafePoint
TSafePoint {.compilerproc, final.} = object
prev: PSafePoint # points to next safe point
exc: ref E_Base
exc: ref Exception
PCallFrame = ptr TCallFrame
TCallFrame {.importc, nodecl, final.} = object
@ -97,7 +97,7 @@ proc rawWriteStackTrace(): string =
else:
result = "No stack traceback available\n"
proc raiseException(e: ref E_Base, ename: cstring) {.
proc raiseException(e: ref Exception, ename: cstring) {.
compilerproc, asmNoStackFrame.} =
e.name = ename
if excHandler != nil:
@ -120,24 +120,24 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
proc reraiseException() {.compilerproc, asmNoStackFrame.} =
if excHandler == nil:
raise newException(ENoExceptionToReraise, "no exception to reraise")
raise newException(ReraiseError, "no exception to reraise")
else:
asm """throw excHandler.exc;"""
proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} =
raise newException(EOverflow, "over- or underflow")
raise newException(OverflowError, "over- or underflow")
proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} =
raise newException(EDivByZero, "divison by zero")
raise newException(DivByZeroError, "divison by zero")
proc raiseRangeError() {.compilerproc, noreturn.} =
raise newException(EOutOfRange, "value out of range")
raise newException(RangeError, "value out of range")
proc raiseIndexError() {.compilerproc, noreturn.} =
raise newException(EInvalidIndex, "index out of bounds")
raise newException(IndexError, "index out of bounds")
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(EInvalidField, f & " is not accessible")
raise newException(FieldError, f & " is not accessible")
proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} =
asm """
@ -260,7 +260,7 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
"""
type
TDocument {.importc.} = object of TObject
TDocument {.importc.} = object of RootObj
write: proc (text: cstring) {.nimcall.}
writeln: proc (text: cstring) {.nimcall.}
createAttribute: proc (identifier: cstring): ref TNode {.nimcall.}
@ -283,7 +283,7 @@ type
DocumentTypeNode,
DocumentFragmentNode,
NotationNode
TNode* {.importc.} = object of TObject
TNode* {.importc.} = object of RootObj
attributes*: seq[ref TNode]
childNodes*: seq[ref TNode]
data*: cstring
@ -515,7 +515,7 @@ proc isFatPointer(ti: PNimType): bool =
proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} =
case n.kind
of nkNone: sysAssert(false, "nimCopyAux")
of nkSlot:
@ -566,7 +566,7 @@ proc nimCopy(x: pointer, ti: PNimType): pointer =
else:
result = x
proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} =
proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} =
case ti.kind
of tyPtr, tyRef, tyVar, tyNil:
if not isFatPointer(ti):
@ -621,7 +621,7 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
if x == subclass: return # optimized fast path
while x != subclass:
if x == nil:
raise newException(EInvalidObjectConversion, "invalid object conversion")
raise newException(ObjectConversionError, "invalid object conversion")
x = x.base
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =

View file

@ -305,22 +305,26 @@ proc running*[TArg](t: TThread[TArg]): bool {.inline.} =
## returns true if `t` is running.
result = t.dataFn != nil
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
## waits for the thread `t` to finish.
when hostOS == "windows":
when hostOS == "windows":
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
## waits for the thread `t` to finish.
discard waitForSingleObject(t.sys, -1'i32)
else:
discard pthread_join(t.sys, nil)
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
## waits for every thread in `t` to finish.
when hostOS == "windows":
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
## waits for every thread in `t` to finish.
var a: array[0..255, TSysThread]
sysAssert a.len >= t.len, "a.len >= t.len"
for i in 0..t.high: a[i] = t[i].sys
discard waitForMultipleObjects(t.len.int32,
discard waitForMultipleObjects(t.len.int32,
cast[ptr TSysThread](addr(a)), 1, -1)
else:
else:
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
## waits for the thread `t` to finish.
discard pthread_join(t.sys, nil)
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
## waits for every thread in `t` to finish.
for i in 0..t.high: joinThread(t[i])
when false:
@ -335,27 +339,37 @@ when false:
when declared(registerThread): unregisterThread(addr(t))
t.dataFn = nil
proc createThread*[TArg](t: var TThread[TArg],
tp: proc (arg: TArg) {.thread.},
param: TArg) =
## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
## don't need to pass any data to the thread.
when TArg isnot void: t.data = param
t.dataFn = tp
when hasSharedHeap: t.stackSize = ThreadStackSize
when hostOS == "windows":
when hostOS == "windows":
proc createThread*[TArg](t: var TThread[TArg],
tp: proc (arg: TArg) {.thread.},
param: TArg) =
## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
## don't need to pass any data to the thread.
when TArg isnot void: t.data = param
t.dataFn = tp
when hasSharedHeap: t.stackSize = ThreadStackSize
var dummyThreadId: int32
t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg],
addr(t), 0'i32, dummyThreadId)
if t.sys <= 0:
raise newException(EResourceExhausted, "cannot create thread")
else:
raise newException(ResourceExhaustedError, "cannot create thread")
else:
proc createThread*[TArg](t: var TThread[TArg],
tp: proc (arg: TArg) {.thread.},
param: TArg) =
## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
## don't need to pass any data to the thread.
when TArg isnot void: t.data = param
t.dataFn = tp
when hasSharedHeap: t.stackSize = ThreadStackSize
var a {.noinit.}: Tpthread_attr
pthread_attr_init(a)
pthread_attr_setstacksize(a, ThreadStackSize)
if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0:
raise newException(EResourceExhausted, "cannot create thread")
raise newException(ResourceExhaustedError, "cannot create thread")
proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} =
## returns the thread ID of `t`.