Merge branch 'devel' into araq
This commit is contained in:
commit
1eaeccc15d
616 changed files with 73547 additions and 36764 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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>".}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.} =
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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, "\\\""
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.}
|
||||
|
|
|
|||
|
|
@ -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]))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue