summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-02-03 07:58:31 +0100
committerAndreas Rumpf <rumpf_a@web.de>2018-02-03 07:58:31 +0100
commit4e0b3fefa3f7d09762404667dbe94558d65868fb (patch)
treed88ea7fa92ce3aca0545bfa2fbda901ec36e8691
parent992fd38487afc706d3271beda8189dadfca53592 (diff)
parent4f9ae61695bc7a03b15a8d26ee1e702582db76af (diff)
downloadNim-4e0b3fefa3f7d09762404667dbe94558d65868fb.tar.gz
Merge branch 'devel' into araq-overloading-symmetry
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/cgen.nim2
-rw-r--r--compiler/extccomp.nim2
-rw-r--r--compiler/gorgeimpl.nim2
-rw-r--r--compiler/importer.nim4
-rw-r--r--compiler/jsgen.nim18
-rw-r--r--compiler/modules.nim2
-rw-r--r--compiler/rodread.nim2
-rw-r--r--compiler/rodutils.nim16
-rw-r--r--compiler/rodwrite.nim2
-rw-r--r--compiler/semfold.nim1
-rw-r--r--compiler/sempass2.nim19
-rw-r--r--doc/manual/types.txt6
-rw-r--r--lib/pure/os.nim15
-rw-r--r--lib/pure/securehash.nim195
-rw-r--r--lib/pure/sha1.nim195
-rw-r--r--lib/system/sysio.nim22
-rw-r--r--tests/ccgbugs/t7079.nim9
-rw-r--r--tests/system/io.nim25
-rw-r--r--tools/niminst/niminst.nim2
-rw-r--r--web/website.ini2
21 files changed, 300 insertions, 243 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 5c70bda18..a19dbf7de 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -10,7 +10,7 @@
 # abstract syntax tree + symbol table
 
 import
-  msgs, hashes, nversion, options, strutils, securehash, ropes, idents,
+  msgs, hashes, nversion, options, strutils, sha1, ropes, idents,
   intsets, idgen
 
 type
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 12e640d96..6051f2804 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -11,7 +11,7 @@
 
 import
   ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
-  nversion, nimsets, msgs, securehash, bitsets, idents, types,
+  nversion, nimsets, msgs, sha1, bitsets, idents, types,
   ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
   condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
   lowerings, semparallel, tables, sets, ndi
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 62990593d..3a6fcde5a 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -14,7 +14,7 @@
 
 import
   ropes, os, strutils, osproc, platform, condsyms, options, msgs,
-  securehash, streams
+  sha1, streams
 
 #from debuginfo import writeDebugInfo
 
diff --git a/compiler/gorgeimpl.nim b/compiler/gorgeimpl.nim
index 2c51752cd..9cc6eb2ba 100644
--- a/compiler/gorgeimpl.nim
+++ b/compiler/gorgeimpl.nim
@@ -9,7 +9,7 @@
 
 ## Module that implements ``gorge`` for the compiler.
 
-import msgs, securehash, os, osproc, streams, strutils, options
+import msgs, sha1, os, osproc, streams, strutils, options
 
 proc readOutput(p: Process): (string, int) =
   result[0] = ""
diff --git a/compiler/importer.nim b/compiler/importer.nim
index 46d675b27..3d7f62464 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -11,7 +11,7 @@
 
 import
   intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
-  semdata, passes, renderer, modulepaths
+  semdata, passes, renderer, modulepaths, sigmatch
 
 proc evalImport*(c: PContext, n: PNode): PNode
 proc evalFrom*(c: PContext, n: PNode): PNode
@@ -149,7 +149,7 @@ proc myImportModule(c: PContext, n: PNode): PSym =
         localError(n.info, errGenerated, "A module cannot import itself")
     if sfDeprecated in result.flags:
       message(n.info, warnDeprecated, result.name.s)
-    #suggestSym(n.info, result, false)
+    suggestSym(n.info, result, c.graph.usageSym, false)
 
 proc impMod(c: PContext; it: PNode) =
   let m = myImportModule(c, it)
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 6f40e7031..3288241d9 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -31,7 +31,7 @@ implements the required case distinction.
 
 import
   ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
-  nversion, nimsets, msgs, securehash, bitsets, idents, types, os,
+  nversion, nimsets, msgs, sha1, bitsets, idents, types, os,
   times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
   intsets, cgmeth, lowerings
 
@@ -2284,11 +2284,17 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
     r.kind = resExpr
   of nkFloatLit..nkFloat64Lit:
     let f = n.floatVal
-    if f != f: r.res = rope"NaN"
-    elif f == 0.0: r.res = rope"0.0"
-    elif f == 0.5 * f:
-      if f > 0.0: r.res = rope"Infinity"
-      else: r.res = rope"-Infinity"
+    case classify(f)
+    of fcNaN:
+      r.res = rope"NaN"
+    of fcNegZero:
+      r.res = rope"-0.0"
+    of fcZero:
+      r.res = rope"0.0"
+    of fcInf:
+      r.res = rope"Infinity"
+    of fcNegInf:
+      r.res = rope"-Infinity"
     else: r.res = rope(f.toStrMaxPrecision)
     r.kind = resExpr
   of nkCallKinds:
diff --git a/compiler/modules.nim b/compiler/modules.nim
index 4763ac79b..e94c5c162 100644
--- a/compiler/modules.nim
+++ b/compiler/modules.nim
@@ -10,7 +10,7 @@
 ## Implements the module handling, including the caching of modules.
 
 import
-  ast, astalgo, magicsys, securehash, rodread, msgs, cgendata, sigmatch, options,
+  ast, astalgo, magicsys, sha1, rodread, msgs, cgendata, sigmatch, options,
   idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs
 
 when false:
diff --git a/compiler/rodread.nim b/compiler/rodread.nim
index dfa8fc52b..5abac1d79 100644
--- a/compiler/rodread.nim
+++ b/compiler/rodread.nim
@@ -90,7 +90,7 @@
 
 import
   os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
-  ropes, idents, securehash, idgen, types, rodutils, memfiles, tables
+  ropes, idents, sha1, idgen, types, rodutils, memfiles, tables
 
 type
   TReasonForRecompile* = enum ## all the reasons that can trigger recompilation
diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim
index 0456e9349..0d9c7112f 100644
--- a/compiler/rodutils.nim
+++ b/compiler/rodutils.nim
@@ -8,18 +8,22 @@
 #
 
 ## Serialization utilities for the compiler.
-import strutils
+import strutils, math
 
 proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.}
 
 proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
-  if f != f:
+  case classify(f)
+  of fcNaN:
     result = "NAN"
-  elif f == 0.0:
+  of fcNegZero:
+    result = "-0.0" & literalPostfix
+  of fcZero:
     result = "0.0" & literalPostfix
-  elif f == 0.5 * f:
-    if f > 0.0: result = "INF"
-    else: result = "-INF"
+  of fcInf:
+    result = "INF"
+  of fcNegInf:
+    result = "-INF"
   else:
     when defined(nimNoArrayToCstringConversion):
       result = newString(81)
diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim
index 9aed33ec9..24d897fb1 100644
--- a/compiler/rodwrite.nim
+++ b/compiler/rodwrite.nim
@@ -13,7 +13,7 @@
 
 import
   intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform,
-  condsyms, ropes, idents, securehash, rodread, passes, idgen,
+  condsyms, ropes, idents, sha1, rodread, passes, idgen,
   rodutils, modulepaths
 
 from modulegraphs import ModuleGraph
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 55cdc334c..59c55010f 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -225,6 +225,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
   of mDivF64:
     if getFloat(b) == 0.0:
       if getFloat(a) == 0.0: result = newFloatNodeT(NaN, n)
+      elif getFloat(b).classify == fcNegZero: result = newFloatNodeT(-Inf, n)
       else: result = newFloatNodeT(Inf, n)
     else:
       result = newFloatNodeT(getFloat(a) / getFloat(b), n)
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index e560c18c8..25525d412 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -593,17 +593,14 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
   notNilCheck(tracked, n, paramType)
 
 proc breaksBlock(n: PNode): bool =
-  case n.kind
-  of nkStmtList, nkStmtListExpr:
-    for c in n:
-      if breaksBlock(c): return true
-  of nkBreakStmt, nkReturnStmt, nkRaiseStmt:
-    return true
-  of nkCallKinds:
-    if n.sons[0].kind == nkSym and sfNoReturn in n.sons[0].sym.flags:
-      return true
-  else:
-    discard
+  # sematic check doesn't allow statements after raise, break, return or
+  # call to noreturn proc, so it is safe to check just the last statements
+  var it = n
+  while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
+    it = it.lastSon
+
+  result = it.kind in {nkBreakStmt, nkReturnStmt, nkRaiseStmt} or
+    it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
 
 proc trackCase(tracked: PEffects, n: PNode) =
   track(tracked, n.sons[0])
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index 1477995dd..8a90dee05 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -181,11 +181,11 @@ Nim exceptions: `FloatInvalidOpError`:idx:, `FloatDivByZeroError`:idx:,
 and `FloatInexactError`:idx:.
 These exceptions inherit from the `FloatingPointError`:idx: base class.
 
-Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
+Nim provides the pragmas `nanChecks`:idx: and `infChecks`:idx: to control
 whether the IEEE exceptions are ignored or trap a Nim exception:
 
 .. code-block:: nim
-  {.NanChecks: on, InfChecks: on.}
+  {.nanChecks: on, infChecks: on.}
   var a = 1.0
   var b = 0.0
   echo b / b # raises FloatInvalidOpError
@@ -195,7 +195,7 @@ In the current implementation ``FloatDivByZeroError`` and ``FloatInexactError``
 are never raised. ``FloatOverflowError`` is raised instead of
 ``FloatDivByZeroError``.
 There is also a `floatChecks`:idx: pragma that is a short-cut for the
-combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
+combination of ``nanChecks`` and ``infChecks`` pragmas. ``floatChecks`` are
 turned off as default.
 
 The only operations that are affected by the ``floatChecks`` pragma are
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index a5db4ed22..f8936f549 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -139,10 +139,15 @@ proc findExe*(exe: string, followSymlinks: bool = true;
   ## is added the `ExeExts <#ExeExts>`_ file extensions if it has none.
   ## If the system supports symlinks it also resolves them until it
   ## meets the actual file. This behavior can be disabled if desired.
-  for ext in extensions:
-    result = addFileExt(exe, ext)
-    if existsFile(result): return
-  var path = string(getEnv("PATH"))
+  template checkCurrentDir() =
+    for ext in extensions:
+      result = addFileExt(exe, ext)
+      if existsFile(result): return
+  when defined(posix):
+    if '/' in exe: checkCurrentDir()
+  else:
+    checkCurrentDir()
+  let path = string(getEnv("PATH"))
   for candidate in split(path, PathSep):
     when defined(windows):
       var x = (if candidate[0] == '"' and candidate[^1] == '"':
@@ -824,7 +829,7 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
 
 iterator walkDirRec*(dir: string, yieldFilter = {pcFile},
                      followFilter = {pcDir}): string {.tags: [ReadDirEffect].} =
-  ## Recursively walks over the directory `dir` and yields for each file 
+  ## Recursively walks over the directory `dir` and yields for each file
   ## or directory in `dir`.
   ## The full path for each file or directory is returned.
   ## **Warning**:
diff --git a/lib/pure/securehash.nim b/lib/pure/securehash.nim
index b18095ff6..06da80e4c 100644
--- a/lib/pure/securehash.nim
+++ b/lib/pure/securehash.nim
@@ -1,195 +1,6 @@
-#
-#
-#           The Nim Compiler
-#        (c) Copyright 2015 Nim Contributors
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
 
-import strutils
 
-const Sha1DigestSize = 20
+## This module is a deprecated alias for the ``sha1`` module.
+{.deprecated.}
 
-type
-  Sha1Digest = array[0 .. Sha1DigestSize-1, uint8]
-  SecureHash* = distinct Sha1Digest
-
-# Copyright (c) 2011, Micael Hildenborg
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# * Neither the name of Micael Hildenborg nor the
-#   names of its contributors may be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Ported to Nim by Erik O'Leary
-
-type
-  Sha1State* = array[0 .. 5-1, uint32]
-  Sha1Buffer = array[0 .. 80-1, uint32]
-
-template clearBuffer(w: Sha1Buffer, len = 16) =
-  zeroMem(addr(w), len * sizeof(uint32))
-
-proc init*(result: var Sha1State) =
-  result[0] = 0x67452301'u32
-  result[1] = 0xefcdab89'u32
-  result[2] = 0x98badcfe'u32
-  result[3] = 0x10325476'u32
-  result[4] = 0xc3d2e1f0'u32
-
-proc innerHash(state: var Sha1State, w: var Sha1Buffer) =
-  var
-    a = state[0]
-    b = state[1]
-    c = state[2]
-    d = state[3]
-    e = state[4]
-
-  var round = 0
-
-  template rot(value, bits: uint32): uint32 =
-    (value shl bits) or (value shr (32u32 - bits))
-
-  template sha1(fun, val: uint32) =
-    let t = rot(a, 5) + fun + e + val + w[round]
-    e = d
-    d = c
-    c = rot(b, 30)
-    b = a
-    a = t
-
-  template process(body: untyped) =
-    w[round] = rot(w[round - 3] xor w[round - 8] xor w[round - 14] xor w[round - 16], 1)
-    body
-    inc(round)
-
-  template wrap(dest, value: untyped) =
-    let v = dest + value
-    dest = v
-
-  while round < 16:
-    sha1((b and c) or (not b and d), 0x5a827999'u32)
-    inc(round)
-
-  while round < 20:
-    process:
-      sha1((b and c) or (not b and d), 0x5a827999'u32)
-
-  while round < 40:
-    process:
-      sha1(b xor c xor d, 0x6ed9eba1'u32)
-
-  while round < 60:
-    process:
-      sha1((b and c) or (b and d) or (c and d), 0x8f1bbcdc'u32)
-
-  while round < 80:
-    process:
-      sha1(b xor c xor d, 0xca62c1d6'u32)
-
-  wrap state[0], a
-  wrap state[1], b
-  wrap state[2], c
-  wrap state[3], d
-  wrap state[4], e
-
-proc sha1(src: cstring; len: int): Sha1Digest =
-  #Initialize state
-  var state: Sha1State
-  init(state)
-
-  #Create w buffer
-  var w: Sha1Buffer
-
-  #Loop through all complete 64byte blocks.
-  let byteLen = len
-  let endOfFullBlocks = byteLen - 64
-  var endCurrentBlock = 0
-  var currentBlock = 0
-
-  while currentBlock <= endOfFullBlocks:
-    endCurrentBlock = currentBlock + 64
-
-    var i = 0
-    while currentBlock < endCurrentBlock:
-      w[i] = uint32(src[currentBlock+3]) or
-             uint32(src[currentBlock+2]) shl 8'u32 or
-             uint32(src[currentBlock+1]) shl 16'u32 or
-             uint32(src[currentBlock])   shl 24'u32
-      currentBlock += 4
-      inc(i)
-
-    innerHash(state, w)
-
-  #Handle last and not full 64 byte block if existing
-  endCurrentBlock = byteLen - currentBlock
-  clearBuffer(w)
-  var lastBlockBytes = 0
-
-  while lastBlockBytes < endCurrentBlock:
-
-    var value = uint32(src[lastBlockBytes + currentBlock]) shl
-                ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
-
-    w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or value
-    inc(lastBlockBytes)
-
-  w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or (
-    0x80'u32 shl ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
-  )
-
-  if endCurrentBlock >= 56:
-    innerHash(state, w)
-    clearBuffer(w)
-
-  w[15] = uint32(byteLen) shl 3
-  innerHash(state, w)
-
-  # Store hash in result pointer, and make sure we get in in the correct order
-  # on both endian models.
-  for i in 0 .. Sha1DigestSize-1:
-    result[i] = uint8((int(state[i shr 2]) shr ((3-(i and 3)) * 8)) and 255)
-
-proc sha1(src: string): Sha1Digest =
-  ## Calculate SHA1 from input string
-  sha1(src, src.len)
-
-proc secureHash*(str: string): SecureHash = SecureHash(sha1(str))
-proc secureHashFile*(filename: string): SecureHash = secureHash(readFile(filename))
-proc `$`*(self: SecureHash): string =
-  result = ""
-  for v in Sha1Digest(self):
-    result.add(toHex(int(v), 2))
-
-proc parseSecureHash*(hash: string): SecureHash =
-  for i in 0 ..< Sha1DigestSize:
-    Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1]))
-
-proc `==`*(a, b: SecureHash): bool =
-  # Not a constant-time comparison, but that's acceptable in this context
-  Sha1Digest(a) == Sha1Digest(b)
-
-
-when isMainModule:
-  let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
-  doAssert hash1 == hash1
-  doAssert parseSecureHash($hash1) == hash1
+include sha1
diff --git a/lib/pure/sha1.nim b/lib/pure/sha1.nim
new file mode 100644
index 000000000..b18095ff6
--- /dev/null
+++ b/lib/pure/sha1.nim
@@ -0,0 +1,195 @@
+#
+#
+#           The Nim Compiler
+#        (c) Copyright 2015 Nim Contributors
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+import strutils
+
+const Sha1DigestSize = 20
+
+type
+  Sha1Digest = array[0 .. Sha1DigestSize-1, uint8]
+  SecureHash* = distinct Sha1Digest
+
+# Copyright (c) 2011, Micael Hildenborg
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# * Neither the name of Micael Hildenborg nor the
+#   names of its contributors may be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Ported to Nim by Erik O'Leary
+
+type
+  Sha1State* = array[0 .. 5-1, uint32]
+  Sha1Buffer = array[0 .. 80-1, uint32]
+
+template clearBuffer(w: Sha1Buffer, len = 16) =
+  zeroMem(addr(w), len * sizeof(uint32))
+
+proc init*(result: var Sha1State) =
+  result[0] = 0x67452301'u32
+  result[1] = 0xefcdab89'u32
+  result[2] = 0x98badcfe'u32
+  result[3] = 0x10325476'u32
+  result[4] = 0xc3d2e1f0'u32
+
+proc innerHash(state: var Sha1State, w: var Sha1Buffer) =
+  var
+    a = state[0]
+    b = state[1]
+    c = state[2]
+    d = state[3]
+    e = state[4]
+
+  var round = 0
+
+  template rot(value, bits: uint32): uint32 =
+    (value shl bits) or (value shr (32u32 - bits))
+
+  template sha1(fun, val: uint32) =
+    let t = rot(a, 5) + fun + e + val + w[round]
+    e = d
+    d = c
+    c = rot(b, 30)
+    b = a
+    a = t
+
+  template process(body: untyped) =
+    w[round] = rot(w[round - 3] xor w[round - 8] xor w[round - 14] xor w[round - 16], 1)
+    body
+    inc(round)
+
+  template wrap(dest, value: untyped) =
+    let v = dest + value
+    dest = v
+
+  while round < 16:
+    sha1((b and c) or (not b and d), 0x5a827999'u32)
+    inc(round)
+
+  while round < 20:
+    process:
+      sha1((b and c) or (not b and d), 0x5a827999'u32)
+
+  while round < 40:
+    process:
+      sha1(b xor c xor d, 0x6ed9eba1'u32)
+
+  while round < 60:
+    process:
+      sha1((b and c) or (b and d) or (c and d), 0x8f1bbcdc'u32)
+
+  while round < 80:
+    process:
+      sha1(b xor c xor d, 0xca62c1d6'u32)
+
+  wrap state[0], a
+  wrap state[1], b
+  wrap state[2], c
+  wrap state[3], d
+  wrap state[4], e
+
+proc sha1(src: cstring; len: int): Sha1Digest =
+  #Initialize state
+  var state: Sha1State
+  init(state)
+
+  #Create w buffer
+  var w: Sha1Buffer
+
+  #Loop through all complete 64byte blocks.
+  let byteLen = len
+  let endOfFullBlocks = byteLen - 64
+  var endCurrentBlock = 0
+  var currentBlock = 0
+
+  while currentBlock <= endOfFullBlocks:
+    endCurrentBlock = currentBlock + 64
+
+    var i = 0
+    while currentBlock < endCurrentBlock:
+      w[i] = uint32(src[currentBlock+3]) or
+             uint32(src[currentBlock+2]) shl 8'u32 or
+             uint32(src[currentBlock+1]) shl 16'u32 or
+             uint32(src[currentBlock])   shl 24'u32
+      currentBlock += 4
+      inc(i)
+
+    innerHash(state, w)
+
+  #Handle last and not full 64 byte block if existing
+  endCurrentBlock = byteLen - currentBlock
+  clearBuffer(w)
+  var lastBlockBytes = 0
+
+  while lastBlockBytes < endCurrentBlock:
+
+    var value = uint32(src[lastBlockBytes + currentBlock]) shl
+                ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
+
+    w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or value
+    inc(lastBlockBytes)
+
+  w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or (
+    0x80'u32 shl ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
+  )
+
+  if endCurrentBlock >= 56:
+    innerHash(state, w)
+    clearBuffer(w)
+
+  w[15] = uint32(byteLen) shl 3
+  innerHash(state, w)
+
+  # Store hash in result pointer, and make sure we get in in the correct order
+  # on both endian models.
+  for i in 0 .. Sha1DigestSize-1:
+    result[i] = uint8((int(state[i shr 2]) shr ((3-(i and 3)) * 8)) and 255)
+
+proc sha1(src: string): Sha1Digest =
+  ## Calculate SHA1 from input string
+  sha1(src, src.len)
+
+proc secureHash*(str: string): SecureHash = SecureHash(sha1(str))
+proc secureHashFile*(filename: string): SecureHash = secureHash(readFile(filename))
+proc `$`*(self: SecureHash): string =
+  result = ""
+  for v in Sha1Digest(self):
+    result.add(toHex(int(v), 2))
+
+proc parseSecureHash*(hash: string): SecureHash =
+  for i in 0 ..< Sha1DigestSize:
+    Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1]))
+
+proc `==`*(a, b: SecureHash): bool =
+  # Not a constant-time comparison, but that's acceptable in this context
+  Sha1Digest(a) == Sha1Digest(b)
+
+
+when isMainModule:
+  let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
+  doAssert hash1 == hash1
+  doAssert parseSecureHash($hash1) == hash1
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index f638b299c..71cbb1c21 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -47,10 +47,16 @@ when not declared(c_fwrite):
 # C routine that is used here:
 proc c_fread(buf: pointer, size, n: csize, f: File): csize {.
   importc: "fread", header: "<stdio.h>", tags: [ReadIOEffect].}
-proc c_fseek(f: File, offset: clong, whence: cint): cint {.
-  importc: "fseek", header: "<stdio.h>", tags: [].}
-proc c_ftell(f: File): clong {.
-  importc: "ftell", header: "<stdio.h>", tags: [].}
+when defined(windows):
+  proc c_fseek(f: File, offset: int64, whence: cint): cint {.
+    importc: "_fseeki64", header: "<stdio.h>", tags: [].}
+  proc c_ftell(f: File): int64 {.
+    importc: "_ftelli64", header: "<stdio.h>", tags: [].}
+else:
+  proc c_fseek(f: File, offset: int64, whence: cint): cint {.
+    importc: "fseeko", header: "<stdio.h>", tags: [].}
+  proc c_ftell(f: File): int64 {.
+    importc: "ftello", header: "<stdio.h>", tags: [].}
 proc c_ferror(f: File): cint {.
   importc: "ferror", header: "<stdio.h>", tags: [].}
 proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize): cint {.
@@ -210,12 +216,12 @@ proc readAllBuffer(file: File): string =
       result.add(buffer)
       break
 
-proc rawFileSize(file: File): int =
+proc rawFileSize(file: File): int64 =
   # this does not raise an error opposed to `getFileSize`
   var oldPos = c_ftell(file)
   discard c_fseek(file, 0, 2) # seek the end of the file
   result = c_ftell(file)
-  discard c_fseek(file, clong(oldPos), 0)
+  discard c_fseek(file, oldPos, 0)
 
 proc endOfFile(f: File): bool =
   var c = c_fgetc(f)
@@ -223,7 +229,7 @@ proc endOfFile(f: File): bool =
   return c < 0'i32
   #result = c_feof(f) != 0
 
-proc readAllFile(file: File, len: int): string =
+proc readAllFile(file: File, len: int64): string =
   # We acquire the filesize beforehand and hope it doesn't change.
   # Speeds things up.
   result = newString(len)
@@ -363,7 +369,7 @@ proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool =
   result = f != nil
 
 proc setFilePos(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) =
-  if c_fseek(f, clong(pos), cint(relativeTo)) != 0:
+  if c_fseek(f, pos, cint(relativeTo)) != 0:
     raiseEIO("cannot set file position")
 
 proc getFilePos(f: File): int64 =
diff --git a/tests/ccgbugs/t7079.nim b/tests/ccgbugs/t7079.nim
new file mode 100644
index 000000000..bfa1b77a6
--- /dev/null
+++ b/tests/ccgbugs/t7079.nim
@@ -0,0 +1,9 @@
+discard """
+  action: run
+  targets: '''c js'''
+"""
+
+import math
+let x = -0.0
+doAssert classify(x) == fcNegZero
+doAssert classify(1 / -0.0) == fcNegInf
\ No newline at end of file
diff --git a/tests/system/io.nim b/tests/system/io.nim
index b0ccfda9f..3d4df806b 100644
--- a/tests/system/io.nim
+++ b/tests/system/io.nim
@@ -1,5 +1,5 @@
 import
-  unittest, osproc, streams, os
+  unittest, osproc, streams, os, strformat
 const STRING_DATA = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
 const TEST_FILE = "tests/testdata/string.txt"
 
@@ -23,3 +23,26 @@ suite "io":
     test "file":
       check:
         readFile(TEST_FILE) == STRING_DATA
+
+
+proc verifyFileSize(sz: int64) =
+  # issue 7121, large file size (2-4GB and >4Gb)
+  const fn = "tmpfile112358"
+  let size_in_mb = sz div 1_000_000
+
+  when defined(windows):
+    discard execProcess(&"fsutil file createnew {fn} {sz}" )
+  else:
+    discard execProcess(&"dd if=/dev/zero of={fn} bs=1000000 count={size_in_mb}")
+
+  doAssert os.getFileSize(fn) == sz # Verify OS filesize by string
+  
+  var f = open(fn)
+  doAssert f.getFileSize() == sz # Verify file handle filesize
+  f.close()
+
+  os.removeFile(fn)
+
+#disable tests for automatic testers
+#for s in [50_000_000'i64, 3_000_000_000, 5_000_000_000]:
+#  verifyFileSize(s)
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index 9c15326b0..c2fe79087 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -15,7 +15,7 @@ when haveZipLib:
 
 import
   os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation,
-  securehash
+  sha1
 
 const
   maxOS = 20 # max number of OSes
diff --git a/web/website.ini b/web/website.ini
index 273c3223d..4420915ab 100644
--- a/web/website.ini
+++ b/web/website.ini
@@ -65,7 +65,7 @@ srcdoc2: "pure/asyncfile;pure/asyncftpclient;pure/lenientops"
 srcdoc2: "pure/md5;pure/rationals"
 srcdoc2: "posix/posix;pure/distros;pure/oswalkdir"
 srcdoc2: "pure/collections/heapqueue"
-srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin;pure/strformat"
+srcdoc2: "pure/fenv;pure/sha1;impure/rdstdin;pure/strformat"
 srcdoc2: "pure/segfaults"
 srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore"
 srcdoc2: "pure/bitops;pure/nimtracker;pure/punycode;pure/volatile;js/asyncjs"