summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgstmts.nim4
-rw-r--r--compiler/cgmeth.nim9
-rw-r--r--compiler/jsgen.nim1
-rw-r--r--compiler/jstypes.nim2
-rw-r--r--doc/tut1.rst12
-rw-r--r--lib/pure/strutils.nim2
-rw-r--r--lib/system/atomics.nim20
-rw-r--r--lib/system/syslocks.nim110
-rw-r--r--nimsuggest/nimsuggest.nim2
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)