Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Andreas Rumpf 2018-01-04 15:59:10 +01:00
commit 464d037c17
31 changed files with 301 additions and 98 deletions

View file

@ -400,11 +400,11 @@ typedef struct TStringDesc* string;
// NAN definition copied from math.h included in the Windows SDK version 10.0.14393.0
#ifndef NAN
#ifndef _HUGE_ENUF
#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
#endif
#define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
#define NAN ((float)(NAN_INFINITY * 0.0F))
# ifndef _HUGE_ENUF
# define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow
# endif
# define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
# define NAN ((float)(NAN_INFINITY * 0.0F))
#endif
#ifndef INF
@ -482,7 +482,6 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
On disagreement, your C compiler will say something like:
"error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */
typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
#endif
#ifdef __cplusplus
# define NIM_EXTERNC extern "C"
@ -509,3 +508,5 @@ extern Libc::Env *genodeEnv;
/* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */
#define NIM_CHECK_SIZE(typ, sz) \
_Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size")
#endif /* NIMBASE_H */

View file

@ -34,7 +34,7 @@ type
{.deprecated: [TSocketHandle: SocketHandle].}
type
Time* {.importc: "time_t", header: "<time.h>".} = distinct int
Time* {.importc: "time_t", header: "<time.h>".} = distinct clong
Timespec* {.importc: "struct timespec",
header: "<time.h>", final, pure.} = object ## struct timespec

View file

@ -1487,7 +1487,7 @@ proc drain*(timeout = 500) =
## if there are no pending operations. In contrast to ``poll`` this
## processes as many events as are available.
if runOnce(timeout):
while runOnce(0): discard
while hasPendingOperations() and runOnce(0): discard
proc poll*(timeout = 500) =
## Waits for completion events and processes them. Raises ``ValueError``

View file

@ -73,10 +73,10 @@ proc add*[A](x: var SharedList[A]; y: A) =
node.d[node.dataLen] = y
inc(node.dataLen)
proc initSharedList*[A](): SharedList[A] =
initLock result.lock
result.head = nil
result.tail = nil
proc init*[A](t: var SharedList[A]) =
initLock t.lock
t.head = nil
t.tail = nil
proc clear*[A](t: var SharedList[A]) =
withLock(t):
@ -92,4 +92,11 @@ proc deinitSharedList*[A](t: var SharedList[A]) =
clear(t)
deinitLock t.lock
proc initSharedList*[A](): SharedList[A] {.deprecated.} =
## Deprecated. Use `init` instead.
## This is not posix compliant, may introduce undefined behavior.
initLock result.lock
result.head = nil
result.tail = nil
{.pop.}

View file

@ -192,19 +192,29 @@ proc del*[A, B](t: var SharedTable[A, B], key: A) =
withLock t:
delImpl()
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] =
proc init*[A, B](t: var SharedTable[A, B], initialSize=64) =
## creates a new hash table that is empty.
##
## `initialSize` needs to be a power of two. If you need to accept runtime
## values for this you could use the ``nextPowerOfTwo`` proc from the
## `math <math.html>`_ module or the ``rightSize`` proc from this module.
assert isPowerOfTwo(initialSize)
result.counter = 0
result.dataLen = initialSize
result.data = cast[KeyValuePairSeq[A, B]](allocShared0(
t.counter = 0
t.dataLen = initialSize
t.data = cast[KeyValuePairSeq[A, B]](allocShared0(
sizeof(KeyValuePair[A, B]) * initialSize))
initLock result.lock
initLock t.lock
proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) =
deallocShared(t.data)
deinitLock t.lock
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] {.deprecated.} =
## Deprecated. Use `init` instead.
## This is not posix compliant, may introduce undefined behavior.
assert isPowerOfTwo(initialSize)
result.counter = 0
result.dataLen = initialSize
result.data = cast[KeyValuePairSeq[A, B]](allocShared0(
sizeof(KeyValuePair[A, B]) * initialSize))
initLock result.lock

View file

@ -257,10 +257,13 @@ proc close*(f: var MemFile) =
when defined(windows):
if f.wasOpened:
error = unmapViewOfFile(f.mem) == 0
lastErr = osLastError()
error = (closeHandle(f.mapHandle) == 0) or error
if f.fHandle != INVALID_HANDLE_VALUE:
error = (closeHandle(f.fHandle) == 0) or error
if not error:
error = closeHandle(f.mapHandle) == 0
if not error and f.fHandle != INVALID_HANDLE_VALUE:
discard closeHandle(f.fHandle)
f.fHandle = INVALID_HANDLE_VALUE
if error:
lastErr = osLastError()
else:
error = munmap(f.mem, f.size) != 0
lastErr = osLastError()

View file

@ -39,7 +39,7 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] =
result.num = x
result.den = 1
proc toRational*(x: float, n: int = high(int32)): Rational[int] =
proc toRational*(x: float, n: int = high(int) shr (sizeof(int) div 2 * 8)): Rational[int] =
## Calculates the best rational numerator and denominator
## that approximates to `x`, where the denominator is
## smaller than `n` (default is the largest possible
@ -323,8 +323,13 @@ when isMainModule:
assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
assert toInt(z) == 0
assert toRational(0.98765432) == 2111111029 // 2137499919
assert toRational(PI) == 817696623 // 260280919
when sizeof(int) == 8:
assert toRational(0.98765432) == 2111111029 // 2137499919
assert toRational(PI) == 817696623 // 260280919
when sizeof(int) == 4:
assert toRational(0.98765432) == 80 // 81
assert toRational(PI) == 355 // 113
assert toRational(0.1) == 1 // 10
assert toRational(0.9) == 9 // 10

View file

@ -176,7 +176,7 @@ proc assertValidDate(monthday: MonthdayRange, month: Month, year: int) {.inline.
assert monthday <= getDaysInMonth(month, year),
$year & "-" & $ord(month) & "-" & $monthday & " is not a valid date"
proc toEpochDay*(monthday: MonthdayRange, month: Month, year: int): int64 =
proc toEpochDay(monthday: MonthdayRange, month: Month, year: int): int64 =
## Get the epoch day from a year/month/day date.
## The epoch day is the number of days since 1970/01/01 (it might be negative).
assertValidDate monthday, month, year
@ -191,7 +191,7 @@ proc toEpochDay*(monthday: MonthdayRange, month: Month, year: int): int64 =
let doe = yoe * 365 + yoe div 4 - yoe div 100 + doy
return era * 146097 + doe - 719468
proc fromEpochDay*(epochday: int64): tuple[monthday: MonthdayRange, month: Month, year: int] =
proc fromEpochDay(epochday: int64): tuple[monthday: MonthdayRange, month: Month, year: int] =
## Get the year/month/day date from a epoch day.
## The epoch day is the number of days since 1970/01/01 (it might be negative).
# Based on http://howardhinnant.github.io/date_algorithms.html
@ -1352,29 +1352,42 @@ else:
proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign, deprecated.} =
## Takes a float which contains the number of seconds since the unix epoch and
## returns a time object.
##
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
Time(since1970)
proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign, deprecated.} =
## Takes an int which contains the number of seconds since the unix epoch and
## returns a time object.
##
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
Time(since1970)
proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.} =
## Returns the time in seconds since the unix epoch.
##
## **Deprecated since v0.18.0:** use ``toUnix`` instead
float(time)
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
## Converts the calendar time `time` to broken-time representation,
## expressed relative to the user's specified time zone.
##
## **Deprecated since v0.18.0:** use ``local`` instead
time.local
proc getGMTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
## Converts the calendar time `time` to broken-down time representation,
## expressed in Coordinated Universal Time (UTC).
## expressed in Coordinated Universal Time (UTC).
##
## **Deprecated since v0.18.0:** use ``utc`` instead
time.utc
proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign, deprecated.} =
## Returns the offset of the local (non-DST) timezone in seconds west of UTC.
##
## **Deprecated since v0.18.0:** use ``now().utcOffset`` to get the current
## utc offset (including DST).
when defined(JS):
return newDate().getTimezoneOffset() * 60
elif defined(freebsd) or defined(netbsd) or defined(openbsd):
@ -1468,4 +1481,4 @@ proc getDayOfWeekJulian*(day, month, year: int): WeekDay {.deprecated.} =
y = year - a
m = month + (12*a) - 2
d = (5 + day + y + (y div 4) + (31*m) div 12) mod 7
result = d.WeekDay
result = d.WeekDay

View file

@ -743,6 +743,18 @@ proc newSeqOfCap*[T](cap: Natural): seq[T] {.
## ``cap``.
discard
when not defined(JS):
proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] =
## creates a new sequence of type ``seq[T]`` with length ``len``.
##
## Only available for numbers types. Note that the sequence will be
## uninitialized. After the creation of the sequence you should assign
## entries to the sequence instead of adding them.
result = newSeqOfCap[T](len)
var s = cast[PGenericSeq](result)
s.len = len
proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
magic: "LengthOpenArray", noSideEffect.}
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}

View file

@ -318,7 +318,7 @@ proc initGC() =
init(gch.marked)
init(gch.additionalRoots)
when hasThreadSupport:
gch.toDispose = initSharedList[pointer]()
init(gch.toDispose)
when useMarkForDebug or useBackupGc:
type

View file

@ -133,7 +133,7 @@ proc initGC() =
init(gch.additionalRoots)
init(gch.greyStack)
when hasThreadSupport:
gch.toDispose = initSharedList[pointer]()
init(gch.toDispose)
# Which color to use for new objects is tricky: When we're marking,
# they have to be *white* so that everything is marked that is only

View file

@ -233,7 +233,7 @@ proc initGC() =
init(gch.allocated)
init(gch.marked)
when hasThreadSupport:
gch.toDispose = initSharedList[pointer]()
init(gch.toDispose)
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
var d = cast[ByteAddress](dest)