diff options
-rw-r--r-- | compiler/ccgstmts.nim | 4 | ||||
-rw-r--r-- | compiler/cgmeth.nim | 9 | ||||
-rw-r--r-- | compiler/jsgen.nim | 1 | ||||
-rw-r--r-- | compiler/jstypes.nim | 2 | ||||
-rw-r--r-- | doc/tut1.rst | 12 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 2 | ||||
-rw-r--r-- | lib/system/atomics.nim | 20 | ||||
-rw-r--r-- | lib/system/syslocks.nim | 110 | ||||
-rw-r--r-- | nimsuggest/nimsuggest.nim | 2 |
9 files changed, 125 insertions, 37 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index cc925b150..a094da783 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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): diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index e14306e56..1165ec932 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -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)) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index eb3fb9f47..ee35356c9 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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: diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index f49bd7668..ae30861e7 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -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]}") % [ diff --git a/doc/tut1.rst b/doc/tut1.rst index 06ee84c0d..436b3880d 100644 --- a/doc/tut1.rst +++ b/doc/tut1.rst @@ -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. diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 9383675f4..458c22f3a 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -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.} = diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 3a43729dc..885b01621 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -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 diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index fb354880f..f61b887ad 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -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) {. + 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 signalSysCond(cond: var SysCond) {. + proc signalSysCondAux(cond: var SysCondObj) {. importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.} - proc deinitSysCond(cond: var SysCond) {.noSideEffect, - importc: "pthread_cond_destroy", header: "<pthread.h>".} + + 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.} diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index c1adb87a1..93a418dd7 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -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) |