Merge branch 'devel' into araq

This commit is contained in:
Andreas Rumpf 2017-11-02 10:46:30 +01:00
commit 1eaeccc15d
616 changed files with 73547 additions and 36764 deletions

View file

@ -301,13 +301,14 @@ proc pageAddr(p: pointer): PChunk {.inline.} =
result = cast[PChunk](cast[ByteAddress](p) and not PageMask)
#sysAssert(Contains(allocator.chunkStarts, pageIndex(result)))
proc writeFreeList(a: MemRegion) =
var it = a.freeChunksList
c_fprintf(stdout, "freeChunksList: %p\n", it)
while it != nil:
c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n",
it, it.next, it.prev, it.size)
it = it.next
when false:
proc writeFreeList(a: MemRegion) =
var it = a.freeChunksList
c_fprintf(stdout, "freeChunksList: %p\n", it)
while it != nil:
c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n",
it, it.next, it.prev, it.size)
it = it.next
const nimMaxHeap {.intdefine.} = 0

View file

@ -103,8 +103,12 @@ proc c_sprintf(buf, frmt: cstring): cint {.
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
# we use it only in a way that cannot lead to security issues
proc c_fileno(f: File): cint {.
importc: "fileno", header: "<fcntl.h>".}
when defined(windows):
proc c_fileno(f: File): cint {.
importc: "_fileno", header: "<stdio.h>".}
else:
proc c_fileno(f: File): cint {.
importc: "fileno", header: "<fcntl.h>".}
proc c_malloc(size: csize): pointer {.
importc: "malloc", header: "<stdlib.h>".}

View file

@ -61,13 +61,17 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
unsureAsgnRef(x, s2)
return
sysAssert(dest != nil, "genericAssignAux 3")
unsureAsgnRef(x, newSeq(mt, seq.len))
var dst = cast[ByteAddress](cast[PPointer](dest)[])
if ntfNoRefs in mt.base.flags:
var ss = nimNewSeqOfCap(mt, seq.len)
cast[PGenericSeq](ss).len = seq.len
unsureAsgnRef(x, ss)
var dst = cast[ByteAddress](cast[PPointer](dest)[])
copyMem(cast[pointer](dst +% GenericSeqSize),
cast[pointer](cast[ByteAddress](s2) +% GenericSeqSize),
seq.len * mt.base.size)
else:
unsureAsgnRef(x, newSeq(mt, seq.len))
var dst = cast[ByteAddress](cast[PPointer](dest)[])
for i in 0..seq.len-1:
genericAssignAux(
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),

View file

@ -127,7 +127,7 @@ proc fileMatches(c, bp: cstring): bool =
proc canonFilename*(filename: cstring): cstring =
## returns 'nil' if the filename cannot be found.
for i in 0 .. <dbgFilenameLen:
for i in 0 .. dbgFilenameLen-1:
result = dbgFilenames[i]
if fileMatches(result, filename): return result
result = nil
@ -261,7 +261,7 @@ proc genericHash(dest: pointer, mt: PNimType): int =
proc dbgRegisterWatchpoint(address: pointer, name: cstring,
typ: PNimType) {.compilerproc.} =
let L = watchPointsLen
for i in 0.. <L:
for i in 0 .. pred(L):
if watchPoints[i].name == name:
# address may have changed:
watchPoints[i].address = address
@ -288,7 +288,7 @@ var
proc checkWatchpoints =
let L = watchPointsLen
for i in 0.. <L:
for i in 0 .. pred(L):
let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ)
if newHash != watchPoints[i].oldValue:
dbgWatchpointHook(watchPoints[i].name)

View file

@ -142,7 +142,10 @@ elif defined(windows) or defined(dos):
dec(m)
k = k div 10
if k == 0: break
result = getProcAddress(cast[THINSTANCE](lib), decorated)
when defined(nimNoArrayToCstringConversion):
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
else:
result = getProcAddress(cast[THINSTANCE](lib), decorated)
if result != nil: return
procAddrError(name)

View file

@ -76,10 +76,10 @@ proc `==`(a, b: StaticStr): bool =
return true
proc `==`(a: StaticStr, b: cstring): bool =
result = c_strcmp(a.data, b) == 0
result = c_strcmp(unsafeAddr a.data, b) == 0
proc write(f: File, s: StaticStr) =
write(f, cstring(s.data))
write(f, cstring(unsafeAddr s.data))
proc listBreakPoints() =
write(stdout, EndbBeg)
@ -260,8 +260,8 @@ proc parseBreakpoint(s: cstring, start: int): Breakpoint =
if result.high == 0: result.high = result.low
i = scanFilename(s, dbgTemp, i)
if dbgTemp.len != 0:
if not hasExt(dbgTemp.data): add(dbgTemp, ".nim")
result.filename = canonFilename(dbgTemp.data.cstring)
if not hasExt(addr dbgTemp.data): add(dbgTemp, ".nim")
result.filename = canonFilename(addr dbgTemp.data)
if result.filename.isNil:
debugOut("[Warning] no breakpoint could be set; unknown filename ")
return
@ -292,12 +292,12 @@ proc dbgEvaluate(stream: File, s: cstring, start: int, f: PFrame) =
i = scanAndAppendWord(s, dbgTemp, i)
for i in 0 .. getGlobalLen()-1:
let v = getGlobal(i)
if c_strcmp(v.name, dbgTemp.data) == 0:
if c_strcmp(v.name, addr dbgTemp.data) == 0:
writeVariable(stream, v)
else:
for i in 0 .. f.len-1:
let v = getLocal(f, i)
if c_strcmp(v.name, dbgTemp.data) == 0:
if c_strcmp(v.name, addr dbgTemp.data) == 0:
writeVariable(stream, v)
proc dbgOut(s: cstring, start: int, currFrame: PFrame) =
@ -306,7 +306,7 @@ proc dbgOut(s: cstring, start: int, currFrame: PFrame) =
if dbgTemp.len == 0:
invalidCommand()
return
var stream = openAppend(dbgTemp.data)
var stream = openAppend(addr dbgTemp.data)
if stream == nil:
debugOut("[Warning] could not open or create file ")
return
@ -320,7 +320,7 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
# just write it to stdout:
listFrame(stdout, currFrame)
else:
var stream = openAppend(dbgTemp.data)
var stream = openAppend(addr dbgTemp.data)
if stream == nil:
debugOut("[Warning] could not open or create file ")
return
@ -369,7 +369,7 @@ proc commandPrompt() =
if not readLine(stdin, dbgUser): break
if dbgUser.len == 0: dbgUser.len = oldLen
# now look what we have to do:
var i = scanWord(dbgUser.data, dbgTemp, 0)
var i = scanWord(addr dbgUser.data, dbgTemp, 0)
template `?`(x: expr): expr = dbgTemp == cstring(x)
if ?"s" or ?"step":
dbgState = dbStepInto
@ -400,13 +400,13 @@ proc commandPrompt() =
prevState = dbgState
prevSkipFrame = dbgSkipToFrame
dbgState = dbSkipCurrent
dbgEvaluate(stdout, dbgUser.data, i, dbgFramePtr)
dbgEvaluate(stdout, addr dbgUser.data, i, dbgFramePtr)
dbgState = prevState
dbgSkipToFrame = prevSkipFrame
elif ?"o" or ?"out":
dbgOut(dbgUser.data, i, dbgFramePtr)
dbgOut(addr dbgUser.data, i, dbgFramePtr)
elif ?"stackframe":
dbgStackFrame(dbgUser.data, i, dbgFramePtr)
dbgStackFrame(addr dbgUser.data, i, dbgFramePtr)
elif ?"w" or ?"where":
dbgShowExecutionPoint()
elif ?"l" or ?"locals":
@ -444,16 +444,16 @@ proc commandPrompt() =
elif ?"bt" or ?"backtrace":
dbgWriteStackTrace(framePtr)
elif ?"b" or ?"break":
createBreakPoint(dbgUser.data, i)
createBreakPoint(addr dbgUser.data, i)
elif ?"breakpoints":
listBreakPoints()
elif ?"toggle":
breakpointToggle(dbgUser.data, i)
breakpointToggle(addr dbgUser.data, i)
elif ?"filenames":
listFilenames()
elif ?"maxdisplay":
var parsed: int
i = scanNumber(dbgUser.data, parsed, i)
i = scanNumber(addr dbgUser.data, parsed, i)
if dbgUser.data[i-1] in {'0'..'9'}:
if parsed == 0: maxDisplayRecDepth = -1
else: maxDisplayRecDepth = parsed

View file

@ -306,8 +306,12 @@ proc raiseExceptionAux(e: ref Exception) =
add(buf, " [")
xadd(buf, e.name, e.name.len)
add(buf, "]\n")
unhandled(buf):
showErrorMessage(buf)
when defined(nimNoArrayToCstringConversion):
template tbuf(): untyped = addr buf
else:
template tbuf(): untyped = buf
unhandled(tbuf()):
showErrorMessage(tbuf())
quitOrDebug()
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =

View file

@ -155,14 +155,15 @@ template setColor(c, col) =
else:
c.refcount = c.refcount and not colorMask or col
proc writeCell(msg: cstring, c: PCell) =
var kind = -1
var typName: cstring = "nil"
if c.typ != nil:
kind = ord(c.typ.kind)
when defined(nimTypeNames):
if not c.typ.name.isNil:
typName = c.typ.name
when defined(logGC):
proc writeCell(msg: cstring, c: PCell) =
var kind = -1
var typName: cstring = "nil"
if c.typ != nil:
kind = ord(c.typ.kind)
when defined(nimTypeNames):
if not c.typ.name.isNil:
typName = c.typ.name
when leakDetector:
c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld from %s(%ld)\n",
@ -642,9 +643,9 @@ when useMarkForDebug or useBackupGc:
forAllChildren(d, waMarkPrecise)
proc markGlobals(gch: var GcHeap) =
for i in 0 .. < globalMarkersLen: globalMarkers[i]()
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
let d = gch.additionalRoots.d
for i in 0 .. < gch.additionalRoots.len: markS(gch, d[i])
for i in 0 .. gch.additionalRoots.len-1: markS(gch, d[i])
when logGC:
var
@ -652,7 +653,7 @@ when logGC:
cycleCheckALen = 0
proc alreadySeen(c: PCell): bool =
for i in 0 .. <cycleCheckALen:
for i in 0 .. cycleCheckALen-1:
if cycleCheckA[i] == c: return true
if cycleCheckALen == len(cycleCheckA):
gcAssert(false, "cycle detection overflow")

View file

@ -487,12 +487,12 @@ proc GC_dumpHeap*(file: File) =
var spaceIter: ObjectSpaceIter
when false:
var d = gch.decStack.d
for i in 0 .. < gch.decStack.len:
for i in 0 .. gch.decStack.len-1:
if isAllocatedPtr(gch.region, d[i]):
c_fprintf(file, "onstack %p\n", d[i])
else:
c_fprintf(file, "onstack_invalid %p\n", d[i])
for i in 0 .. < globalMarkersLen: globalMarkers[i]()
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
while true:
let x = allObjectsAsProc(gch.region, addr spaceIter)
if spaceIter.state < 0: break
@ -579,7 +579,7 @@ proc markIncremental(gch: var GcHeap): bool =
result = true
proc markGlobals(gch: var GcHeap) =
for i in 0 .. < globalMarkersLen: globalMarkers[i]()
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
proc doOperation(p: pointer, op: WalkOp) =
if p == nil: return

View file

@ -450,9 +450,9 @@ when false:
quit 1
proc markGlobals(gch: var GcHeap) =
for i in 0 .. < globalMarkersLen: globalMarkers[i]()
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
let d = gch.additionalRoots.d
for i in 0 .. < gch.additionalRoots.len: mark(gch, d[i])
for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i])
proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
# the addresses are not as cells on the stack, so turn them to cells:

View file

@ -106,7 +106,7 @@ proc cmpic*(a, b: string): int =
## Compares `a` and `b` ignoring case.
cmpIgnoreCase(a, b)
proc getEnv*(key: string): string {.tags: [ReadIOEffect].} =
proc getEnv*(key: string; default = ""): string {.tags: [ReadIOEffect].} =
## Retrieves the environment variable of name `key`.
builtin

View file

@ -16,34 +16,39 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
proc reprFloat(x: float): string {.compilerproc.} = return $x
proc reprPointer(x: pointer): string {.compilerproc.} =
var buf: array[0..59, char]
discard c_sprintf(buf, "%p", x)
return $buf
when defined(nimNoArrayToCstringConversion):
result = newString(60)
let n = c_sprintf(addr result[0], "%p", x)
setLen(result, n)
else:
var buf: array[0..59, char]
discard c_sprintf(buf, "%p", x)
return $buf
proc `$`(x: uint64): string =
if x == 0:
result = "0"
else:
var buf: array[60, char]
result = newString(60)
var i = 0
var n = x
while n != 0:
let nn = n div 10'u64
buf[i] = char(n - 10'u64 * nn + ord('0'))
result[i] = char(n - 10'u64 * nn + ord('0'))
inc i
n = nn
result.setLen i
let half = i div 2
# Reverse
for t in 0 .. < half: swap(buf[t], buf[i-t-1])
result = $buf
for t in 0 .. half-1: swap(result[t], result[i-t-1])
proc reprStrAux(result: var string, s: cstring; len: int) =
if cast[pointer](s) == nil:
add result, "nil"
return
add result, reprPointer(cast[pointer](s)) & "\""
for i in 0.. <len:
for i in 0 .. pred(len):
let c = s[i]
case c
of '"': add result, "\\\""

View file

@ -9,13 +9,13 @@
# The generic ``repr`` procedure for the javascript backend.
proc reprInt(x: int64): string {.compilerproc.} = return $x
proc reprFloat(x: float): string {.compilerproc.} =
proc reprFloat(x: float): string {.compilerproc.} =
# Js toString doesn't differentiate between 1.0 and 1,
# but we do.
if $x == $(x.int): $x & ".0"
else: $x
proc reprPointer(p: pointer): string {.compilerproc.} =
proc reprPointer(p: pointer): string {.compilerproc.} =
# Do we need to generate the full 8bytes ? In js a pointer is an int anyway
var tmp: int
{. emit: """
@ -38,7 +38,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
result = $typ.node.sons[e].name
else:
result = $e & " (invalid data!)"
proc reprChar(x: char): string {.compilerRtl.} =
result = "\'"
case x
@ -50,7 +50,7 @@ proc reprChar(x: char): string {.compilerRtl.} =
proc reprStrAux(result: var string, s: cstring, len: int) =
add(result, "\"")
for i in 0 .. <len:
for i in 0 .. len-1:
let c = s[i]
case c
of '"': add(result, "\\\"")
@ -67,7 +67,7 @@ proc reprStr(s: string): string {.compilerRtl.} =
if cast[pointer](s).isNil:
# Handle nil strings here because they don't have a length field in js
# TODO: check for null/undefined before generating call to length in js?
# Also: c backend repr of a nil string is <pointer>"", but repr of an
# Also: c backend repr of a nil string is <pointer>"", but repr of an
# array of string that is not initialized is [nil, nil, ...] ??
add(result, "nil")
else:
@ -86,7 +86,7 @@ proc addSetElem(result: var string, elem: int, typ: PNimType) =
iterator setKeys(s: int): int {.inline.} =
# The type of s is a lie, but it's expected to be a set.
# Iterate over the JS object representing a set
# Iterate over the JS object representing a set
# and returns the keys as int.
var len: int
var yieldRes: int
@ -124,16 +124,16 @@ proc initReprClosure(cl: var ReprClosure) =
cl.recDepth = -1 # default is to display everything!
cl.indent = 0
proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure)
proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure)
proc reprArray(a: pointer, typ: PNimType,
proc reprArray(a: pointer, typ: PNimType,
cl: var ReprClosure): string {.compilerRtl.} =
var isNilArrayOrSeq: bool
# isnil is not enough here as it would try to deref `a` without knowing what's inside
{. emit: """
if (`a` == null) {
if (`a` == null) {
`isNilArrayOrSeq` = true;
} else if (`a`[0] == null) {
} else if (`a`[0] == null) {
`isNilArrayOrSeq` = true;
} else {
`isNilArrayOrSeq` = false;
@ -146,19 +146,19 @@ proc reprArray(a: pointer, typ: PNimType,
result = if typ.kind == tySequence: "@[" else: "["
var len: int = 0
var i: int = 0
{. emit: "`len` = `a`.length;\n" .}
var dereffed: pointer = a
for i in 0 .. < len:
for i in 0 .. len-1:
if i > 0 :
add(result, ", ")
# advance pointer and point to element at index
{. emit: """
`dereffed`_Idx = `i`;
`dereffed`_Idx = `i`;
`dereffed` = `a`[`dereffed`_Idx];
""" .}
reprAux(result, dereffed, typ.base, cl)
add(result, "]")
proc isPointedToNil(p: pointer): bool {.inline.}=
@ -181,7 +181,7 @@ proc reprRef(result: var string, p: pointer, typ: PNimType,
proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprClosure) =
add(result, "[")
var first: bool = true
var val: pointer = o
if typ.node.len == 0:
@ -192,7 +192,7 @@ proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprCl
reprAux(result, val, typ.node.typ, cl)
else:
# if the object has more than one field, sons is not nil and contains the fields.
for i in 0 .. <typ.node.len:
for i in 0 .. typ.node.len-1:
if first: first = false
else: add(result, ",\n")
@ -214,11 +214,11 @@ proc reprJSONStringify(p: int): string {.compilerRtl.} =
{. emit: "`tmp` = JSON.stringify(`p`);\n" .}
result = $tmp
proc reprAux(result: var string, p: pointer, typ: PNimType,
proc reprAux(result: var string, p: pointer, typ: PNimType,
cl: var ReprClosure) =
if cl.recDepth == 0:
add(result, "...")
return
return
dec(cl.recDepth)
case typ.kind
of tyInt..tyInt64, tyUInt..tyUInt64:

View file

@ -15,9 +15,12 @@
{.push debugger:off .} # the user does not want to trace a part
# of the standard library!
proc c_fdopen(filehandle: cint, mode: cstring): File {.
importc: "fdopen", header: "<stdio.h>".}
when defined(windows):
proc c_fdopen(filehandle: cint, mode: cstring): File {.
importc: "_fdopen", header: "<stdio.h>".}
else:
proc c_fdopen(filehandle: cint, mode: cstring): File {.
importc: "fdopen", header: "<stdio.h>".}
proc c_fputs(c: cstring, f: File): cint {.
importc: "fputs", header: "<stdio.h>", tags: [WriteIOEffect].}
proc c_fgets(c: cstring, n: cint, f: File): cstring {.
@ -401,4 +404,18 @@ proc setStdIoUnbuffered() =
when declared(stdin):
discard c_setvbuf(stdin, nil, IONBF, 0)
when declared(stdout):
proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
when not defined(windows):
proc flockfile(f: File) {.importc, noDecl.}
proc funlockfile(f: File) {.importc, noDecl.}
flockfile(stdout)
for s in args:
discard c_fwrite(s.cstring, s.len, 1, stdout)
const linefeed = "\n" # can be 1 or more chars
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
discard c_fflush(stdout)
when not defined(windows):
funlockfile(stdout)
{.pop.}

View file

@ -142,7 +142,7 @@ var
workersData: array[NumThreads, Worker]
proc setup() =
for i in 0.. <NumThreads:
for i in 0 ..< NumThreads:
workersData[i].taskArrived = createCondVar()
workersData[i].taskStarted = createFastCondVar()
createThread(workers[i], slave, addr(workersData[i]))

View file

@ -24,7 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
if a == b: return 0
if a == nil: return -1
if b == nil: return 1
return c_strcmp(a.data, b.data)
when defined(nimNoArrayToCstringConversion):
return c_strcmp(addr a.data, addr b.data)
else:
return c_strcmp(a.data, b.data)
proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
if a == b: return true
@ -275,7 +278,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
GenericSeqSize +% (i*%elemSize)),
extGetCellType(result).base, waPush)
let len1 = gch.tempStack.len
for i in len0 .. <len1:
for i in len0 ..< len1:
doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic)
gch.tempStack.len = len0
else:
@ -320,7 +323,10 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
proc add*(result: var string; x: float) =
var buf: array[0..64, char]
var n: int = c_sprintf(buf, "%.16g", x)
when defined(nimNoArrayToCstringConversion):
var n: int = c_sprintf(addr buf, "%.16g", x)
else:
var n: int = c_sprintf(buf, "%.16g", x)
var hasDot = false
for i in 0..n-1:
if buf[i] == ',':
@ -332,9 +338,10 @@ proc add*(result: var string; x: float) =
buf[n] = '.'
buf[n+1] = '0'
buf[n+2] = '\0'
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced.
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN'
# of '-1.#IND' are produced.
# We want to get rid of these here:
if buf[n-1] in {'n', 'N'}:
if buf[n-1] in {'n', 'N', 'D', 'd'}:
result.add "nan"
elif buf[n-1] == 'F':
if buf[0] == '-':
@ -342,7 +349,10 @@ proc add*(result: var string; x: float) =
else:
result.add "inf"
else:
result.add buf
var i = 0
while buf[i] != '\0':
result.add buf[i]
inc i
proc nimFloatToStr(f: float): string {.compilerproc.} =
result = newStringOfCap(8)
@ -353,9 +363,9 @@ proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {.
const
IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
powtens = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22]
powtens = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22]
proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
start = 0): int {.compilerProc.} =
@ -507,7 +517,10 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
t[ti-2] = ('0'.ord + abs_exponent mod 10).char; abs_exponent = abs_exponent div 10
t[ti-3] = ('0'.ord + abs_exponent mod 10).char
number = c_strtod(t, nil)
when defined(nimNoArrayToCstringConversion):
number = c_strtod(addr t, nil)
else:
number = c_strtod(t, nil)
proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
result = newStringOfCap(sizeof(x)*4)

View file

@ -398,7 +398,7 @@ template afterThreadRuns() =
threadDestructionHandlers[i]()
when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions):
proc deallocOsPages()
proc deallocOsPages() {.rtl.}
when defined(boehmgc):
type GCStackBaseProc = proc(sb: pointer, t: pointer) {.noconv.}