summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/impure/nre.nim9
-rw-r--r--lib/nimbase.h29
-rw-r--r--lib/pure/collections/tables.nim7
-rw-r--r--lib/pure/terminal.nim2
-rw-r--r--lib/system/alloc.nim7
-rw-r--r--lib/system/nimscript.nim5
-rw-r--r--lib/system/threads.nim6
-rw-r--r--lib/upcoming/asyncdispatch.nim25
8 files changed, 63 insertions, 27 deletions
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim
index 626c3fd6b..dda4b033f 100644
--- a/lib/impure/nre.nim
+++ b/lib/impure/nre.nim
@@ -23,6 +23,15 @@ export options
 ##
 ## A regular expression library for Nim using PCRE to do the hard work.
 ##
+## **Note**: If you love ``sequtils.toSeq`` we have bad news for you. This
+## library doesn't work with it due to documented compiler limitations. As
+## a workaround, use this:
+##
+## .. code-block:: nim
+##
+##    import nre except toSeq
+##
+##
 ## Licencing
 ## ---------
 ##
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 818bff462..a5d2616e7 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -402,16 +402,29 @@ struct TFrame {
   NI16 calldepth;
 };
 
-#define nimfr(proc, file) \
-  TFrame FR; \
-  FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = 0; nimFrame(&FR);
+#ifdef NIM_NEW_MANGLING_RULES
+  #define nimfr_(proc, file) \
+    TFrame FR_; \
+    FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_);
 
-#define nimfrs(proc, file, slots, length) \
-  struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR; \
-  FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = length; nimFrame((TFrame*)&FR);
+  #define nimfrs_(proc, file, slots, length) \
+    struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \
+    FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_);
 
-#define nimln(n, file) \
-  FR.line = n; FR.filename = file;
+  #define nimln_(n, file) \
+    FR_.line = n; FR_.filename = file;
+#else
+  #define nimfr(proc, file) \
+    TFrame FR; \
+    FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = 0; nimFrame(&FR);
+
+  #define nimfrs(proc, file, slots, length) \
+    struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR; \
+    FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = length; nimFrame((TFrame*)&FR);
+
+  #define nimln(n, file) \
+    FR.line = n; FR.filename = file;
+#endif
 
 #define NIM_POSIX_INIT  __attribute__((constructor))
 
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 57e98bf5c..00a81b8d5 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -814,11 +814,14 @@ proc len*[A](t: CountTable[A]): int =
   ## returns the number of keys in `t`.
   result = t.counter
 
-proc clear*[A](t: var CountTable[A] | CountTableRef[A]) =
+proc clear*[A](t: CountTableRef[A]) =
   ## Resets the table so that it is empty.
   clearImpl()
-  t.counter = 0
 
+proc clear*[A](t: var CountTable[A]) =
+  ## Resets the table so that it is empty.
+  clearImpl()
+  
 iterator pairs*[A](t: CountTable[A]): (A, int) =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index 7a8113b2a..31278eabf 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -630,7 +630,7 @@ proc getch*(): char =
   when defined(windows):
     let fd = getStdHandle(STD_INPUT_HANDLE)
     var keyEvent = KEY_EVENT_RECORD()
-    var numRead: cint 
+    var numRead: cint
     while true:
       # Block until character is entered
       doAssert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0)
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 6e7801be5..065b13460 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -295,10 +295,11 @@ proc writeFreeList(a: MemRegion) =
 proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
   when not defined(emscripten):
     if not a.blockChunkSizeIncrease:
-      if a.currMem < 64 * 1024:
+      let usedMem = a.currMem # - a.freeMem
+      if usedMem < 64 * 1024:
         a.nextChunkSize = PageSize*4
       else:
-        a.nextChunkSize = min(roundup(a.currMem shr 2, PageSize), a.nextChunkSize * 2)
+        a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
   var size = size
 
   if size > a.nextChunkSize:
@@ -708,7 +709,7 @@ proc realloc(allocator: var MemRegion, p: pointer, newsize: Natural): pointer =
   if newsize > 0:
     result = alloc0(allocator, newsize)
     if p != nil:
-      copyMem(result, p, ptrSize(p))
+      copyMem(result, p, min(ptrSize(p), newsize))
       dealloc(allocator, p)
   elif p != nil:
     dealloc(allocator, p)
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index f675a9472..73bb91fef 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -293,6 +293,11 @@ template task*(name: untyped; description: string; body: untyped): untyped =
     setCommand "nop"
     `name Task`()
 
+proc cppDefine*(define: string) =
+  ## tell Nim that ``define`` is a C preprocessor ``#define`` and so always
+  ## needs to be mangled.
+  builtin
+
 when not defined(nimble):
   # nimble has its own implementation for these things.
   var
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 3dadfc683..e8b34bf2e 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -195,15 +195,15 @@ else:
     importc: "pthread_setaffinity_np", header: pthreadh.}
 
   when defined(linux):
-    proc syscall(arg: int): int {.varargs, importc: "syscall", header: "<unistd.h>".}
-    var SYS_gettid {.importc, header: "<sys/syscall.h>".}: int
+    proc syscall(arg: clong): clong {.varargs, importc: "syscall", header: "<unistd.h>".}
+    var NR_gettid {.importc: "__NR_gettid", header: "<sys/syscall.h>".}: int
 
     #type Pid {.importc: "pid_t", header: "<sys/types.h>".} = distinct int
     #proc gettid(): Pid {.importc, header: "<sys/types.h>".}
 
     proc getThreadId*(): int =
       ## get the ID of the currently running thread.
-      result = int(syscall(SYS_gettid))
+      result = int(syscall(NR_gettid))
   elif defined(macosx) or defined(bsd):
     proc pthread_threadid_np(y: pointer; x: var uint64): cint {.importc, header: "pthread.h".}
 
diff --git a/lib/upcoming/asyncdispatch.nim b/lib/upcoming/asyncdispatch.nim
index 1fef7182d..74619ab42 100644
--- a/lib/upcoming/asyncdispatch.nim
+++ b/lib/upcoming/asyncdispatch.nim
@@ -1236,9 +1236,14 @@ else:
           newList.add(cb)
 
     withData(p.selector, ident, adata) do:
+      # descriptor still present in queue.
       adata.rwlist = newList & adata.rwlist
       rLength = len(adata.readList)
       wLength = len(adata.writeList)
+    do:
+      # descriptor was unregistered in callback via `unregister()`.
+      rLength = -1
+      wLength = -1
 
   template processCustomCallbacks(ident: untyped) =
     # Process pending custom event callbacks. Custom events are
@@ -1257,11 +1262,16 @@ else:
     var cb = curList[0]
     if not cb(fd.AsyncFD):
       newList.add(cb)
-    else:
-      p.selector.unregister(fd)
 
     withData(p.selector, ident, adata) do:
+      # descriptor still present in queue.
       adata.readList = newList & adata.readList
+      if len(adata.readList) == 0:
+        # if no callbacks registered with descriptor, unregister it.
+        p.selector.unregister(fd)
+    do:
+      # descriptor was unregistered in callback via `unregister()`.
+      discard
 
   proc poll*(timeout = 500) =
     var keys: array[64, ReadyKey]
@@ -1305,15 +1315,10 @@ else:
         # because state `data` can be modified in callback we need to update
         # descriptor events with currently registered callbacks.
         if not custom:
-          var update = false
           var newEvents: set[Event] = {}
-          if rLength > 0:
-            update = true
-            incl(newEvents, Event.Read)
-          if wLength > 0:
-            update = true
-            incl(newEvents, Event.Write)
-          if update:
+          if rLength != -1 and wLength != -1:
+            if rLength > 0: incl(newEvents, Event.Read)
+            if wLength > 0: incl(newEvents, Event.Write)
             p.selector.updateHandle(SocketHandle(fd), newEvents)
         inc(i)