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

This commit is contained in:
Araq
2017-05-14 15:00:34 +02:00
9 changed files with 126 additions and 38 deletions

View File

@@ -332,7 +332,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
var alreadyPoppedCnt = p.inExceptBlock
for i in countup(1, howManyTrys):
if not p.module.compileToCpp:
if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
# Pop safe points generated by try
if alreadyPoppedCnt > 0:
dec alreadyPoppedCnt
@@ -354,7 +354,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
for i in countdown(howManyTrys-1, 0):
p.nestedTryStmts.add(stack[i])
if not p.module.compileToCpp:
if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
# Pop exceptions that was handled by the
# except-blocks we are in
for i in countdown(howManyExcepts-1, 0):

View File

@@ -233,6 +233,12 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
var disp = newNodeI(nkIfStmt, base.info)
var ands = getSysSym("and")
var iss = getSysSym("of")
for col in countup(1, paramLen - 1):
if contains(relevantCols, col):
let param = base.typ.n.sons[col].sym
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
addSon(nilchecks, newTree(nkCall,
newSymNode(getCompilerProc"chckNilDisp"), newSymNode(param)))
for meth in countup(0, high(methods)):
var curr = methods[meth] # generate condition:
var cond: PNode = nil
@@ -242,9 +248,6 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
addSon(isn, newSymNode(iss))
let param = base.typ.n.sons[col].sym
addSon(isn, newSymNode(param))
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
addSon(nilchecks, newTree(nkCall,
newSymNode(getCompilerProc"chckNilDisp"), newSymNode(param)))
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
if cond != nil:
var a = newNodeIT(nkCall, base.info, getSysType(tyBool))

View File

@@ -2272,7 +2272,6 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
genModule(p, n)
add(p.g.code, p.locals)
add(p.g.code, p.body)
globals.unique = p.unique
proc wholeCode(graph: ModuleGraph; m: BModule): Rope =
for prc in globals.forwarded:

View File

@@ -59,7 +59,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
u = rope(lengthOrd(field.typ))
else: internalError(n.info, "genObjectFields(nkRecCase)")
if result != nil: add(result, ", " & tnl)
addf(result, "[SetConstr($1), $2]",
addf(result, "[setConstr($1), $2]",
[u, genObjectFields(p, typ, lastSon(b))])
result = ("{kind: 3, offset: \"$1\", len: $3, " &
"typ: $2, name: $4, sons: [$5]}") % [

View File

@@ -599,7 +599,7 @@ Result variable
A procedure that returns a value has an implicit ``result`` variable declared
that represents the return value. A ``return`` statement with no expression is a
shorthand for ``return result``. The ``result`` value is always returned
automatically at the end a procedure if there is no ``return`` statement at
automatically at the end of a procedure if there is no ``return`` statement at
the exit.
.. code-block:: nim
@@ -1074,8 +1074,8 @@ at runtime by 0, the second by 1 and so on. For example:
Direction = enum
north, east, south, west
var x = south # `x` is of type `Direction`; its value is `south`
echo x # writes "south" to `stdout`
var x = south # `x` is of type `Direction`; its value is `south`
echo x # writes "south" to `stdout`
All the comparison operators can be used with enumeration types.
@@ -1132,11 +1132,11 @@ A subrange type is a range of values from an integer or enumeration type
.. code-block:: nim
type
Subrange = range[0..5]
MySubrange = range[0..5]
``Subrange`` is a subrange of ``int`` which can only hold the values 0
to 5. Assigning any other value to a variable of type ``Subrange`` is a
``MySubrange`` is a subrange of ``int`` which can only hold the values 0
to 5. Assigning any other value to a variable of type ``MySubrange`` is a
compile-time or runtime error. Assignments from the base type to one of its
subrange types (and vice versa) are allowed.

View File

@@ -1881,6 +1881,8 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault,
## of significant digits to be printed.
## `precision`'s default value is the maximum number of meaningful digits
## after the decimal point for Nim's ``float`` type.
##
## If ``precision == 0``, it tries to format it nicely.
result = formatBiggestFloat(f, format, precision, decimalSep)
proc trimZeros*(x: var string) {.noSideEffect.} =

View File

@@ -165,8 +165,22 @@ when someGcc and hasThreadSupport:
template fence*() = atomicThreadFence(ATOMIC_SEQ_CST)
elif defined(vcc) and hasThreadSupport:
proc addAndFetch*(p: ptr int, val: int): int {.
importc: "_InterlockedExchangeAdd", header: "<intrin.h>".}
when defined(cpp):
when sizeof(int) == 8:
proc addAndFetch*(p: ptr int, val: int): int {.
importcpp: "_InterlockedExchangeAdd64(static_cast<NI volatile *>(#), #)",
header: "<intrin.h>".}
else:
proc addAndFetch*(p: ptr int, val: int): int {.
importcpp: "_InterlockedExchangeAdd(static_cast<NI volatile *>(#), #)",
header: "<intrin.h>".}
else:
when sizeof(int) == 8:
proc addAndFetch*(p: ptr int, val: int): int {.
importc: "_InterlockedExchangeAdd64", header: "<intrin.h>".}
else:
proc addAndFetch*(p: ptr int, val: int): int {.
importc: "_InterlockedExchangeAdd", header: "<intrin.h>".}
proc fence*() {.importc: "_ReadWriteBarrier", header: "<intrin.h>".}
@@ -180,6 +194,7 @@ proc atomicInc*(memLoc: var int, x: int = 1): int =
result = atomic_add_fetch(memLoc.addr, x, ATOMIC_RELAXED)
elif defined(vcc) and hasThreadSupport:
result = addAndFetch(memLoc.addr, x)
inc(result, x)
else:
inc(memLoc, x)
result = memLoc
@@ -192,6 +207,7 @@ proc atomicDec*(memLoc: var int, x: int = 1): int =
result = atomic_add_fetch(memLoc.addr, -x, ATOMIC_RELAXED)
elif defined(vcc) and hasThreadSupport:
result = addAndFetch(memLoc.addr, -x)
dec(result, x)
else:
dec(memLoc, x)
result = memLoc

View File

@@ -99,7 +99,7 @@ elif defined(genode):
else:
type
SysLock {.importc: "pthread_mutex_t", pure, final,
SysLockObj {.importc: "pthread_mutex_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
@@ -111,7 +111,7 @@ else:
when defined(linux) and defined(amd64):
abi: array[4 div sizeof(cint), cint] # actually a cint
SysCond {.importc: "pthread_cond_t", pure, final,
SysCondObj {.importc: "pthread_cond_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
@@ -119,8 +119,62 @@ else:
SysLockType = distinct cint
proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {.
proc initSysLockAux(L: var SysLockObj, attr: ptr SysLockAttr) {.
importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
proc deinitSysAux(L: var SysLockObj) {.noSideEffect,
importc: "pthread_mutex_destroy", header: "<pthread.h>".}
proc acquireSysAux(L: var SysLockObj) {.noSideEffect,
importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc tryAcquireSysAux(L: var SysLockObj): cint {.noSideEffect,
importc: "pthread_mutex_trylock", header: "<pthread.h>".}
proc releaseSysAux(L: var SysLockObj) {.noSideEffect,
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
when defined(ios):
# iOS will behave badly if sync primitives are moved in memory. In order
# to prevent this once and for all, we're doing an extra malloc when
# initializing the primitive.
type
SysLock = ptr SysLockObj
SysCond = ptr SysCondObj
when not declared(c_malloc):
proc c_malloc(size: csize): pointer {.
importc: "malloc", header: "<stdlib.h>".}
proc c_free(p: pointer) {.
importc: "free", header: "<stdlib.h>".}
proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) =
L = cast[SysLock](c_malloc(sizeof(SysLockObj)))
initSysLockAux(L[], attr)
proc deinitSys(L: var SysLock) =
deinitSysAux(L[])
c_free(L)
template acquireSys(L: var SysLock) =
acquireSysAux(L[])
template tryAcquireSys(L: var SysLock): bool =
tryAcquireSysAux(L[]) == 0'i32
template releaseSys(L: var SysLock) =
releaseSysAux(L[])
else:
type
SysLock = SysLockObj
SysCond = SysCondObj
template initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) =
initSysLockAux(L, attr)
template deinitSys(L: var SysLock) =
deinitSysAux(L)
template acquireSys(L: var SysLock) =
acquireSysAux(L)
template tryAcquireSys(L: var SysLock): bool =
tryAcquireSysAux(L) == 0'i32
template releaseSys(L: var SysLock) =
releaseSysAux(L)
when insideRLocksModule:
proc SysLockType_Reentrant: SysLockType =
@@ -130,27 +184,39 @@ else:
proc setSysLockType(a: var SysLockAttr, t: SysLockType) {.
importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.}
proc acquireSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc tryAcquireSysAux(L: var SysLock): cint {.noSideEffect,
importc: "pthread_mutex_trylock", header: "<pthread.h>".}
proc tryAcquireSys(L: var SysLock): bool {.inline.} =
result = tryAcquireSysAux(L) == 0'i32
proc releaseSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
proc deinitSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_destroy", header: "<pthread.h>".}
when not insideRLocksModule:
proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {.
else:
proc initSysCondAux(cond: var SysCondObj, cond_attr: pointer) {.
importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
proc signalSysCond(cond: var SysCond) {.
importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
proc deinitSysCond(cond: var SysCond) {.noSideEffect,
proc deinitSysCondAux(cond: var SysCondObj) {.noSideEffect,
importc: "pthread_cond_destroy", header: "<pthread.h>".}
proc waitSysCondAux(cond: var SysCondObj, lock: var SysLockObj) {.
importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
proc signalSysCondAux(cond: var SysCondObj) {.
importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
when defined(ios):
proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) =
cond = cast[SysCond](c_malloc(sizeof(SysCondObj)))
initSysCondAux(cond[], cond_attr)
proc deinitSysCond(cond: var SysCond) =
deinitSysCondAux(cond[])
c_free(cond)
template waitSysCond(cond: var SysCond, lock: var SysLock) =
waitSysCondAux(cond[], lock[])
template signalSysCond(cond: var SysCond) =
signalSysCondAux(cond[])
else:
template initSysCond(cond: var SysCond, cond_attr: pointer = nil) =
initSysCondAux(cond, cond_attr)
template deinitSysCond(cond: var SysCond) =
deinitSysCondAux(cond)
template waitSysCond(cond: var SysCond, lock: var SysLock) =
waitSysCondAux(cond, lock)
template signalSysCond(cond: var SysCond) =
signalSysCondAux(cond)
{.pop.}

View File

@@ -595,6 +595,8 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
raise newException(IOError,
"Cannot find Nim standard library: Nim compiler not in PATH")
gPrefixDir = binaryPath.splitPath().head.parentDir()
if not dirExists(gPrefixDir / "lib"): gPrefixDir = ""
#msgs.writelnHook = proc (line: string) = log(line)
myLog("START " & gProjectFull)