diff options
-rw-r--r-- | compiler/astalgo.nim | 16 | ||||
-rw-r--r-- | compiler/sem.nim | 1 | ||||
-rw-r--r-- | compiler/semcall.nim | 1 | ||||
-rw-r--r-- | lib/pure/math.nim | 32 | ||||
-rw-r--r-- | lib/pure/parseutils.nim | 3 | ||||
-rw-r--r-- | lib/system/gc_regions.nim | 60 | ||||
-rw-r--r-- | lib/system/jssys.nim | 15 | ||||
-rw-r--r-- | lib/wrappers/openssl.nim | 4 | ||||
-rw-r--r-- | tests/template/tgenerictemplates.nim | 24 |
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") + |