Merge branch 'devel' into araq-big-refactoring

This commit is contained in:
Andreas Rumpf
2018-05-27 13:38:09 +02:00
9 changed files with 115 additions and 41 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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]:

View File

@@ -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

View File

@@ -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);
};
}""".}

View File

@@ -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{.

View File

@@ -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")