summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/astalgo.nim16
-rw-r--r--compiler/sem.nim1
-rw-r--r--compiler/semcall.nim1
-rw-r--r--lib/pure/math.nim32
-rw-r--r--lib/pure/parseutils.nim3
-rw-r--r--lib/system/gc_regions.nim60
-rw-r--r--lib/system/jssys.nim15
-rw-r--r--lib/wrappers/openssl.nim4
-rw-r--r--tests/template/tgenerictemplates.nim24
9 files changed, 115 insertions, 41 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 7079e77cc..5912f1359 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -33,22 +33,22 @@ when declared(echo):
 
 template mdbg*: bool {.dirty.} =
   when compiles(c.module):
-    c.module.fileIdx.int32 == gProjectMainIdx
+    c.module.fileIdx.int32 == c.config.projectMainIdx
   elif compiles(c.c.module):
-    c.c.module.fileIdx.int32 == gProjectMainIdx
+    c.c.module.fileIdx.int32 == c.c.config.projectMainIdx
   elif compiles(m.c.module):
-    m.c.module.fileIdx.int32 == gProjectMainIdx
+    m.c.module.fileIdx.int32 == m.c.config.projectMainIdx
   elif compiles(cl.c.module):
-    cl.c.module.fileIdx.int32 == gProjectMainIdx
+    cl.c.module.fileIdx.int32 == cl.c.config.projectMainIdx
   elif compiles(p):
     when compiles(p.lex):
-      p.lex.fileIdx.int32 == gProjectMainIdx
+      p.lex.fileIdx.int32 == p.lex.config.projectMainIdx
     else:
-      p.module.module.fileIdx.int32 == gProjectMainIdx
+      p.module.module.fileIdx.int32 == p.config.projectMainIdx
   elif compiles(m.module.fileIdx):
-    m.module.fileIdx.int32 == gProjectMainIdx
+    m.module.fileIdx.int32 == m.config.projectMainIdx
   elif compiles(L.fileIdx):
-    L.fileIdx.int32 == gProjectMainIdx
+    L.fileIdx.int32 == L.config.projectMainIdx
   else:
     error()
 
diff --git a/compiler/sem.nim b/compiler/sem.nim
index b7dd1df7a..6b3287df5 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -38,6 +38,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
 proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
 proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
 proc semStmt(c: PContext, n: PNode): PNode
+proc semOpAux(c: PContext, n: PNode)
 proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
 proc addParams(c: PContext, n: PNode, kind: TSymKind)
 proc maybeAddResult(c: PContext, s: PSym, n: PNode)
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 894d2ebb2..9c7b9afde 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -254,6 +254,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
   var f = n.sons[0]
   if f.kind == nkBracketExpr:
     # fill in the bindings:
+    semOpAux(c, f)
     initialBinding = f
     f = f.sons[0]
   else:
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 9e590debc..49d87f007 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -21,6 +21,8 @@ include "system/inclrtl"
 {.push debugger:off .} # the user does not want to trace a part
                        # of the standard library!
 
+import bitops
+
 proc binom*(n, k: int): int {.noSideEffect.} =
   ## Computes the binomial coefficient
   if k <= 0: return 1
@@ -455,16 +457,42 @@ proc `^`*[T](x: T, y: Natural): T =
     x *= x
 
 proc gcd*[T](x, y: T): T =
-  ## Computes the greatest common divisor of ``x`` and ``y``.
+  ## Computes the greatest common (positive) divisor of ``x`` and ``y``.
   ## Note that for floats, the result cannot always be interpreted as
   ## "greatest decimal `z` such that ``z*N == x and z*M == y``
   ## where N and M are positive integers."
-  var (x,y) = (x,y)
+  var (x, y) = (x, y)
   while y != 0:
     x = x mod y
     swap x, y
   abs x
 
+proc gcd*(x, y: SomeInteger): SomeInteger =
+  ## Computes the greatest common (positive) divisor of ``x`` and ``y``.
+  ## Using binary GCD (aka Stein's) algorithm.
+  when x is SomeSignedInt:
+    var x = abs(x)
+  else:
+    var x = x
+  when y is SomeSignedInt:
+    var y = abs(y)
+  else:
+    var y = y
+
+  if x == 0:
+    return y
+  if y == 0:
+    return x
+
+  let shift = countTrailingZeroBits(x or y)
+  y = y shr countTrailingZeroBits(y)
+  while x != 0:
+    x = x shr countTrailingZeroBits(x)
+    if y > x:
+      swap y, x
+    x -= y
+  y shl shift
+
 proc lcm*[T](x, y: T): T =
   ## Computes the least common multiple of ``x`` and ``y``.
   x div gcd(x, y) * y
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index d77790fe0..d54f1454b 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -197,6 +197,9 @@ proc parseUntil*(s: string, token: var string, until: string,
   ## parses a token and stores it in ``token``. Returns
   ## the number of the parsed characters or 0 in case of an error. A token
   ## consists of any character that comes before the `until`  token.
+  if until.len == 0:
+    token.setLen(0)
+    return 0
   var i = start
   while i < s.len:
     if s[i] == until[0]:
diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim
index a27aaaa88..10df0a2cb 100644
--- a/lib/system/gc_regions.nim
+++ b/lib/system/gc_regions.nim
@@ -70,8 +70,9 @@ type
     bump: pointer
     head, tail: Chunk
     nextChunkSize, totalSize: int
-    freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
-    holes: SizedFreeEntry
+    when false:
+      freeLists: array[MaxSmallObject div MemAlign, FreeEntry]
+      holes: SizedFreeEntry
     when hasThreadSupport:
       lock: SysLock
 
@@ -145,21 +146,22 @@ proc allocSlowPath(r: var MemRegion; size: int) =
   r.remaining = s - sizeof(BaseChunk)
 
 proc allocFast(r: var MemRegion; size: int): pointer =
-  if size <= MaxSmallObject:
-    var it = r.freeLists[size div MemAlign]
-    if it != nil:
-      r.freeLists[size div MemAlign] = it.next
-      return pointer(it)
-  else:
-    var it = r.holes
-    var prev: SizedFreeEntry = nil
-    while it != nil:
-      if it.size >= size:
-        if prev != nil: prev.next = it.next
-        else: r.holes = it.next
+  when false:
+    if size <= MaxSmallObject:
+      var it = r.freeLists[size div MemAlign]
+      if it != nil:
+        r.freeLists[size div MemAlign] = it.next
         return pointer(it)
-      prev = it
-      it = it.next
+    else:
+      var it = r.holes
+      var prev: SizedFreeEntry = nil
+      while it != nil:
+        if it.size >= size:
+          if prev != nil: prev.next = it.next
+          else: r.holes = it.next
+          return pointer(it)
+        prev = it
+        it = it.next
   if size > r.remaining:
     allocSlowPath(r, size)
   sysAssert(size <= r.remaining, "size <= r.remaining")
@@ -184,15 +186,16 @@ proc dealloc(r: var MemRegion; p: pointer; size: int) =
   # it is benefitial to not use the free lists here:
   if r.bump -! size == p:
     dec r.bump, size
-  elif size <= MaxSmallObject:
-    let it = cast[FreeEntry](p)
-    it.next = r.freeLists[size div MemAlign]
-    r.freeLists[size div MemAlign] = it
-  else:
-    let it = cast[SizedFreeEntry](p)
-    it.size = size
-    it.next = r.holes
-    r.holes = it
+  when false:
+    if size <= MaxSmallObject:
+      let it = cast[FreeEntry](p)
+      it.next = r.freeLists[size div MemAlign]
+      r.freeLists[size div MemAlign] = it
+    else:
+      let it = cast[SizedFreeEntry](p)
+      it.size = size
+      it.next = r.holes
+      r.holes = it
 
 proc deallocAll(r: var MemRegion; head: Chunk) =
   var it = head
@@ -220,9 +223,10 @@ proc setObstackPtr*(r: var MemRegion; sp: StackPtr) =
   if sp.current.next != nil:
     deallocAll(r, sp.current.next)
     sp.current.next = nil
-    # better leak this memory than be sorry:
-    for i in 0..high(r.freeLists): r.freeLists[i] = nil
-    r.holes = nil
+    when false:
+      # better leak this memory than be sorry:
+      for i in 0..high(r.freeLists): r.freeLists[i] = nil
+      r.holes = nil
   #else:
   #  deallocAll(r, r.head)
   #  r.head = nil
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index 56a9f6575..e12bab184 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -332,7 +332,7 @@ proc cmpStrings(a, b: string): int {.asmNoStackFrame, compilerProc.} =
     return `a`.length - `b`.length;
   """
 
-proc cmp(x, y: string): int = 
+proc cmp(x, y: string): int =
   return cmpStrings(x, y)
 
 proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
@@ -750,3 +750,16 @@ when defined(nodejs):
 else:
   # Deprecated. Use `alert` defined in dom.nim
   proc alert*(s: cstring) {.importc, nodecl, deprecated.}
+
+# Workaround for IE, IE up to version 11 lacks 'Math.trunc'. We produce
+# 'Math.trunc' for Nim's ``div`` and ``mod`` operators:
+when not defined(nodejs):
+  {.emit: """
+  if (!Math.trunc) {
+    Math.trunc = function(v) {
+      v = +v;
+      if (!isFinite(v)) return v;
+
+      return (v - v % 1)   ||   (v < 0 ? -0 : v === 0 ? v : 0);
+    };
+  }""".}
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index 6609dc245..a24575d11 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -390,7 +390,7 @@ proc ERR_peek_last_error*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
 
 proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
 
-when not useWinVersion and not defined(macosx) and not defined(android):
+when not useWinVersion and not defined(macosx) and not defined(android) and not defined(nimNoAllocForSSL):
   proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl,
     dynlib: DLLUtilName, importc.}
 
@@ -404,7 +404,7 @@ when not useWinVersion and not defined(macosx) and not defined(android):
     if p != nil: dealloc(p)
 
 proc CRYPTO_malloc_init*() =
-  when not useWinVersion and not defined(macosx) and not defined(android):
+  when not useWinVersion and not defined(macosx) and not defined(android) and not defined(nimNoAllocForSSL):
     CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper)
 
 proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{.
diff --git a/tests/template/tgenerictemplates.nim b/tests/template/tgenerictemplates.nim
index 2c83bc0ec..142505b1a 100644
--- a/tests/template/tgenerictemplates.nim
+++ b/tests/template/tgenerictemplates.nim
@@ -11,3 +11,27 @@ template someTemplate[T](): tuple[id: int32, obj: T] =
 
 let ret = someTemplate[SomeObj]()
 
+# https://github.com/nim-lang/Nim/issues/7829
+proc inner*[T](): int =
+  discard
+
+template outer*[A](): untyped =
+  inner[A]()
+
+template outer*[B](x: int): untyped =
+  inner[B]()
+
+var i1 = outer[int]()
+var i2 = outer[int](i1)
+
+# https://github.com/nim-lang/Nim/issues/7883
+template t1[T: int|int64](s: string): T =
+   var t: T
+   t
+
+template t1[T: int|int64](x: int, s: string): T =
+   var t: T
+   t
+
+var i3: int = t1[int]("xx")
+