summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-09-16 11:36:49 +0200
committerAraq <rumpf_a@web.de>2015-09-16 11:36:49 +0200
commitc9a2fa54c7055c16892e9664dd64d8fc68918c07 (patch)
treeb67fca3d93765f677de696f4f8b1ed50b031b164
parent1251fc76c32bdd50a3b9540e0cd80b0c435051ce (diff)
parentd24eaf084b4be17e43f262d4127a91993ae6f7cd (diff)
downloadNim-c9a2fa54c7055c16892e9664dd64d8fc68918c07.tar.gz
Merge branch 'devel' into fix_bracket_expr
-rw-r--r--compiler/aliases.nim2
-rw-r--r--compiler/jstypes.nim5
-rw-r--r--compiler/vm.nim13
-rw-r--r--lib/pure/json.nim13
-rw-r--r--lib/pure/net.nim12
-rw-r--r--lib/pure/rawsockets.nim70
-rw-r--r--lib/system/repr.nim20
-rw-r--r--lib/windows/winlean.nim8
-rw-r--r--tests/alias/talias.nim5
-rw-r--r--web/news.txt20
10 files changed, 155 insertions, 13 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim
index 3d3fc9a79..4b592ee60 100644
--- a/compiler/aliases.nim
+++ b/compiler/aliases.nim
@@ -146,7 +146,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
     # go down recursively; this is quite demanding:
     const
       Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
-                  nkCheckedFieldExpr}
+                  nkCheckedFieldExpr, nkHiddenAddr}
       Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
       DerefKinds = {nkHiddenDeref, nkDerefExpr}
     case b.kind
diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim
index 851938327..832d9996c 100644
--- a/compiler/jstypes.nim
+++ b/compiler/jstypes.nim
@@ -116,8 +116,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
          [name, genTypeInfo(p, typ.sons[0])])
 
 proc genTypeInfo(p: PProc, typ: PType): Rope =
-  var t = typ
-  if t.kind == tyGenericInst: t = lastSon(t)
+  let t = typ.skipTypes({tyGenericInst})
   result = "NTI$1" % [rope(t.id)]
   if containsOrIncl(p.g.typeInfoGenerated, t.id): return
   case t.kind
@@ -141,7 +140,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
               [result, rope(ord(t.kind))]
     prepend(p.g.typeInfo, s)
     addf(p.g.typeInfo, "$1.base = $2;$n",
-         [result, genTypeInfo(p, typ.sons[1])])
+         [result, genTypeInfo(p, t.sons[1])])
   of tyEnum: genEnumInfo(p, t, result)
   of tyObject: genObjectInfo(p, t, result)
   of tyTuple: genTupleInfo(p, t, result)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 0db287c6a..4dd3b5232 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -320,8 +320,19 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool =
       dest.node.strVal = if src.intVal == 0: "false" else: "true"
     of tyFloat..tyFloat128:
       dest.node.strVal = $src.floatVal
-    of tyString, tyCString:
+    of tyString:
       dest.node.strVal = src.node.strVal
+    of tyCString:
+      if src.node.kind == nkBracket:
+        # Array of chars
+        var strVal = ""
+        for son in src.node.sons:
+          let c = char(son.intVal)
+          if c == '\0': break
+          strVal.add(c)
+        dest.node.strVal = strVal
+      else:
+        dest.node.strVal = src.node.strVal
     of tyChar:
       dest.node.strVal = $chr(src.intVal)
     else:
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 540a1a8eb..abf6305f2 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -1074,9 +1074,9 @@ when not defined(js):
     ## for nice error messages.
     var p: JsonParser
     p.open(s, filename)
+    defer: p.close()
     discard getTok(p) # read first token
     result = p.parseJson()
-    p.close()
 
   proc parseJson*(buffer: string): JsonNode =
     ## Parses JSON from `buffer`.
@@ -1203,6 +1203,17 @@ when isMainModule:
   testJson{["c", "d"]} = %true
   assert(testJson["c"]["d"].bval)
 
+  # make sure no memory leek when parsing invalid string
+  let startMemory = getOccupiedMem()
+  for i in 0 .. 10000:
+    try:
+      discard parseJson"""{ invalid"""
+    except:
+      discard
+  # memory diff should less than 2M
+  assert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024)
+
+
   # test `$`
   let stringified = $testJson
   let parsedAgain = parseJson(stringified)
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 141543c70..0ce5b4d25 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
   var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
   result = res != 0
 
+proc getLocalAddr*(socket: Socket): (string, Port) =
+  ## Get the socket's local address and port number.
+  ##
+  ## This is high-level interface for `getsockname`:idx:.
+  getLocalAddr(socket.fd, socket.domain)
+
+proc getPeerAddr*(socket: Socket): (string, Port) =
+  ## Get the socket's peer address and port number.
+  ##
+  ## This is high-level interface for `getpeername`:idx:.
+  getPeerAddr(socket.fd, socket.domain)
+
 proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
   tags: [WriteIOEffect].} =
   ## Sets option ``opt`` to a boolean value specified by ``value``.
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index 7873e7226..f5860ef28 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
     raiseOSError(osLastError())
   result = Port(rawsockets.ntohs(name.sin_port))
 
+proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+  ## returns the socket's local address and port number.
+  ##
+  ## Similar to POSIX's `getsockname`:idx:.
+  case domain
+  of AF_INET:
+    var name: Sockaddr_in
+    when useWinVersion:
+      name.sin_family = int16(ord(AF_INET))
+    else:
+      name.sin_family = posix.AF_INET
+    var namelen = sizeof(name).SockLen
+    if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+  of AF_INET6:
+    var name: Sockaddr_in6
+    when useWinVersion:
+      name.sin6_family = int16(ord(AF_INET6))
+    else:
+      name.sin6_family = posix.AF_INET6
+    var namelen = sizeof(name).SockLen
+    if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+    var buf: array[64, char]
+    if inet_ntop(name.sin6_family.cint,
+                 addr name, buf.cstring, sizeof(buf).int32).isNil:
+      raiseOSError(osLastError())
+    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+  else:
+    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
+proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+  ## returns the socket's peer address and port number.
+  ##
+  ## Similar to POSIX's `getpeername`:idx:
+  case domain
+  of AF_INET:
+    var name: Sockaddr_in
+    when useWinVersion:
+      name.sin_family = int16(ord(AF_INET))
+    else:
+      name.sin_family = posix.AF_INET
+    var namelen = sizeof(name).SockLen
+    if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+  of AF_INET6:
+    var name: Sockaddr_in6
+    when useWinVersion:
+      name.sin6_family = int16(ord(AF_INET6))
+    else:
+      name.sin6_family = posix.AF_INET6
+    var namelen = sizeof(name).SockLen
+    if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                   addr(namelen)) == -1'i32:
+      raiseOSError(osLastError())
+    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+    var buf: array[64, char]
+    if inet_ntop(name.sin6_family.cint,
+                 addr name, buf.cstring, sizeof(buf).int32).isNil:
+      raiseOSError(osLastError())
+    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+  else:
+    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
 proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
   tags: [ReadIOEffect].} =
   ## getsockopt for integer options.
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index b4188527f..1f81a0813 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -21,9 +21,22 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
   return $buf
 
 proc `$`(x: uint64): string =
-  var buf: array [0..59, char]
-  discard c_sprintf(buf, "%llu", x)
-  return $buf
+  if x == 0:
+    result = "0"
+  else:
+    var buf: array [60, char]
+    var i = 0
+    var n = x
+    while n != 0:
+      let nn = n div 10'u64
+      buf[i] = char(n - 10'u64 * nn + ord('0'))
+      inc i
+      n = nn
+
+    let half = i div 2
+    # Reverse
+    for t in 0 .. < half: swap(buf[t], buf[i-t-1])
+    result = $buf
 
 proc reprStrAux(result: var string, s: string) =
   if cast[pointer](s) == nil:
@@ -294,4 +307,3 @@ when not defined(useNimRtl):
       reprAux(result, addr(p), typ, cl)
     add result, "\n"
     deinitReprClosure(cl)
-
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 24015dd3a..84dac6d79 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -409,7 +409,7 @@ type
     bytes*: array[0..15, char]
 
   Sockaddr_in6* {.importc: "SOCKADDR_IN6",
-                   header: "winsock2.h".} = object
+                   header: "ws2tcpip.h".} = object
     sin6_family*: int16
     sin6_port*: int16 # unsigned
     sin6_flowinfo*: int32 # unsigned
@@ -511,6 +511,9 @@ proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
 proc getsockname*(s: SocketHandle, name: ptr SockAddr,
                   namelen: ptr SockLen): cint {.
   stdcall, importc: "getsockname", dynlib: ws2dll.}
+proc getpeername*(s: SocketHandle, name: ptr SockAddr,
+                  namelen: ptr SockLen): cint {.
+  stdcall, importc, dynlib: ws2dll.}
 proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
                  optlen: ptr SockLen): cint {.
   stdcall, importc: "getsockopt", dynlib: ws2dll.}
@@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
 proc inet_ntoa*(i: InAddr): cstring {.
   stdcall, importc, dynlib: ws2dll.}
 
+proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
+            stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
+
 const
   MAXIMUM_WAIT_OBJECTS* = 0x00000040
 
diff --git a/tests/alias/talias.nim b/tests/alias/talias.nim
index 6addc4704..810ea2095 100644
--- a/tests/alias/talias.nim
+++ b/tests/alias/talias.nim
@@ -30,7 +30,7 @@ type
     c: char
     se: seq[TA]
 
-proc p(param1, param2: TC): TC =
+proc p(param1, param2: TC, param3: var TC): TC =
   var
     local: TC
     plocal: ptr TC
@@ -43,6 +43,7 @@ proc p(param1, param2: TC): TC =
   plocal2[] ?<| local
 
   param1 ?<| param2
+  local ?<| param3
 
   local.arr[0] !<| param1
   local.arr !<| param1
@@ -62,5 +63,5 @@ var
 a <| a
 a !<| b
 
-discard p(x, x)
+discard p(x, x, x)
 
diff --git a/web/news.txt b/web/news.txt
index 9f533de8e..aaa27cfee 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -305,6 +305,26 @@ News
     (`#2183 <https://github.com/Araq/Nim/issues/2183>`_)
   - Fixed "gctest segfaults with --gc:markandsweep on x86_64"
     (`#2305 <https://github.com/Araq/Nim/issues/2305>`_)
+  - Fixed "Coroutine changes break compilation on unsupported architectures"
+    (`#3245 <https://github.com/Araq/Nim/issues/3245>`_)
+  - Fixed "Bugfix: Windows 32bit  TinyCC support issue fixed"
+    (`#3237 <https://github.com/Araq/Nim/issues/3237>`_)
+  - Fixed "db_mysql getValue() followed by exec() causing error"
+    (`#3220 <https://github.com/Araq/Nim/issues/3220>`_)
+  - Fixed "xmltree.newEntity creates xnCData instead of xnEntity"
+    (`#3282 <https://github.com/Araq/Nim/issues/3282>`_)
+  - Fixed "Methods and modules don't work together"
+    (`#2590 <https://github.com/Araq/Nim/issues/2590>`_)
+  - Fixed "String slicing not working in the vm"
+    (`#3300 <https://github.com/Araq/Nim/issues/3300>`_)
+  - Fixed "internal error: evalOp(mTypeOf)"
+    (`#3230 <https://github.com/Araq/Nim/issues/3230>`_)
+  - Fixed "#! source code prefix collides with Unix Shebang"
+    (`#2559 <https://github.com/Araq/Nim/issues/2559>`_)
+  - Fixed "wrong codegen for constant object"
+    (`#3195 <https://github.com/Araq/Nim/issues/3195>`_)
+  - Fixed "Doc comments inside procs with implicit returns don't work"
+    (`#1528 <https://github.com/Araq/Nim/issues/1528>`_)
 
 
 2015-05-04 Version 0.11.2 released