diff options
author | Araq <rumpf_a@web.de> | 2014-08-14 00:02:39 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-08-14 00:02:39 +0200 |
commit | 27b9d10570078c35a5d1b59010ccc6c1a3927f04 (patch) | |
tree | ffb852b72130f8de8026f961edfca296ab221e06 | |
parent | f3d530e482249215da56cf1898edd20b51d4480d (diff) | |
parent | add0a0e9bc5383923eef9c764788feb810f8edc6 (diff) | |
download | Nim-27b9d10570078c35a5d1b59010ccc6c1a3927f04.tar.gz |
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
-rw-r--r-- | compiler/cgen.nim | 25 | ||||
-rw-r--r-- | lib/pure/math.nim | 7 | ||||
-rw-r--r-- | lib/system.nim | 6 | ||||
-rw-r--r-- | lib/wrappers/zmq.nim | 322 |
4 files changed, 29 insertions, 331 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index d3f661466..51444e108 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -954,8 +954,7 @@ proc genMainProc(m: BModule) = "\tsystemInit();$N" & "$1" & "$2" & - "$3" & - "$4" + "$3" MainProcs = "\tNimMain();$N" @@ -963,10 +962,19 @@ proc genMainProc(m: BModule) = MainProcsWithResult = MainProcs & "\treturn nim_program_result;$N" + # The use of a volatile function pointer to call NimMainInner + # prevents inlining of the NimMainInner function and dependent + # functions, which might otherwise merge their stack frames. NimMainBody = - "N_CDECL(void, NimMain)(void) {$N" & + "N_CDECL(void, NimMainInner)(void) {$N" & "\tPreMain();$N" & "$1" & + "}$N$N" & + "N_CDECL(void, NimMain)(void) {$N" & + "\tvoid (*volatile inner)();$N" & + "\tinner = NimMainInner;$N" & + "$2" & + "\t(*inner)();$N" & "}$N$N" PosixNimMain = @@ -1034,14 +1042,15 @@ proc genMainProc(m: BModule) = if optEndb in gOptions: gBreakpoints.app(m.genFilenames) - let initStackBottomCall = if emulatedThreadVars() or - platform.targetOS == osStandalone: "".toRope - else: ropecg(m, "\t#initStackBottom();$N") + let initStackBottomCall = + if emulatedThreadVars() or + platform.targetOS == osStandalone: "".toRope + else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") inc(m.labels) appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [ - mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit]) + mainDatInit, gBreakpoints, otherModsInit]) - appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)]) + appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) diff --git a/lib/pure/math.nim b/lib/pure/math.nim index e76e96da5..8af09114b 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -279,8 +279,13 @@ proc `mod`*(x, y: float): float = result = if y == 0.0: x else: x - y * (x/y).floor proc random*[T](x: TSlice[T]): T = + ## For a slice `a .. b` returns a value in the range `a .. b-1`. result = random(x.b - x.a) + x.a - + +proc random[T](a: openarray[T]): T = + ## returns a random element from the openarray `a`. + result = a[random(a.low..a.len)] + type TRunningStat* {.pure,final.} = object ## an accumulator for statistical data n*: int ## number of pushed data diff --git a/lib/system.nim b/lib/system.nim index 3dc7e308e..8ab3ee2e5 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2182,6 +2182,12 @@ when not defined(JS): #and not defined(NimrodVM): locals = addr(locals) setStackBottom(locals) + proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} = + # We need to keep initStackBottom around for now to avoid + # bootstrapping problems. + when defined(setStackBottom): + setStackBottom(locals) + var strDesc: TNimType diff --git a/lib/wrappers/zmq.nim b/lib/wrappers/zmq.nim deleted file mode 100644 index 9826ab813..000000000 --- a/lib/wrappers/zmq.nim +++ /dev/null @@ -1,322 +0,0 @@ -# Nimrod wrapper of 0mq -# Generated by c2nim with modifications and enhancement from Andreas Rumpf -# Original licence follows: - -# -# Copyright (c) 2007-2011 iMatix Corporation -# Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file -# -# This file is part of 0MQ. -# -# 0MQ is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# 0MQ is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -# Generated from zmq version 2.1.5 - -## Nimrod 0mq wrapper. This file contains the low level C wrappers as well as -## some higher level constructs. The higher level constructs are easily -## recognizable because they are the only ones that have documentation. -## -## Example of a client: -## -## .. code-block:: nimrod -## import zmq -## -## var connection = zmq.open("tcp://localhost:5555", server=false) -## echo("Connecting...") -## for i in 0..10: -## echo("Sending hello...", i) -## send(connection, "Hello") -## var reply = receive(connection) -## echo("Received ...", reply) -## close(connection) -## -## Example of a server: -## -## .. code-block:: nimrod -## -## import zmq -## var connection = zmq.open("tcp://*:5555", server=true) -## while True: -## var request = receive(connection) -## echo("Received: ", request) -## send(connection, "World") -## close(connection) - -{.deadCodeElim: on.} -when defined(windows): - const - zmqdll* = "zmq.dll" -elif defined(macosx): - const - zmqdll* = "libzmq.dylib" -else: - const - zmqdll* = "libzmq.so" - -# A number random enough not to collide with different errno ranges on -# different OSes. The assumption is that error_t is at least 32-bit type. -const - HAUSNUMERO* = 156384712 - # On Windows platform some of the standard POSIX errnos are not defined. - ENOTSUP* = (HAUSNUMERO + 1) - EPROTONOSUPPORT* = (HAUSNUMERO + 2) - ENOBUFS* = (HAUSNUMERO + 3) - ENETDOWN* = (HAUSNUMERO + 4) - EADDRINUSE* = (HAUSNUMERO + 5) - EADDRNOTAVAIL* = (HAUSNUMERO + 6) - ECONNREFUSED* = (HAUSNUMERO + 7) - EINPROGRESS* = (HAUSNUMERO + 8) - # Native 0MQ error codes. - EFSM* = (HAUSNUMERO + 51) - ENOCOMPATPROTO* = (HAUSNUMERO + 52) - ETERM* = (HAUSNUMERO + 53) - EMTHREAD* = (HAUSNUMERO + 54) - # Maximal size of "Very Small Message". VSMs are passed by value - # to avoid excessive memory allocation/deallocation. - # If VMSs larger than 255 bytes are required, type of 'vsm_size' - # field in msg_t structure should be modified accordingly. - MAX_VSM_SIZE* = 30 - - POLLIN* = 1 - POLLOUT* = 2 - POLLERR* = 4 - - STREAMER* = 1 - FORWARDER* = 2 - QUEUE* = 3 - - PAIR* = 0 - PUB* = 1 - SUB* = 2 - REQ* = 3 - REP* = 4 - DEALER* = 5 - ROUTER* = 6 - PULL* = 7 - PUSH* = 8 - XPUB* = 9 - XSUB* = 10 - XREQ* = DEALER # Old alias, remove in 3.x - XREP* = ROUTER # Old alias, remove in 3.x - UPSTREAM* = PULL # Old alias, remove in 3.x - DOWNSTREAM* = PUSH # Old alias, remove in 3.x - -type - # Message types. These integers may be stored in 'content' member of the - # message instead of regular pointer to the data. - TMsgTypes* = enum - DELIMITER = 31, - VSM = 32 - # Message flags. MSG_SHARED is strictly speaking not a message flag - # (it has no equivalent in the wire format), however, making it a flag - # allows us to pack the stucture tighter and thus improve performance. - TMsgFlags* = enum - MSG_MORE = 1, - MSG_SHARED = 128, - MSG_MASK = 129 # Merges all the flags - # A message. Note that 'content' is not a pointer to the raw data. - # Rather it is pointer to zmq::msg_content_t structure - # (see src/msg_content.hpp for its definition). - TMsg*{.pure, final.} = object - content*: pointer - flags*: char - vsm_size*: char - vsm_data*: array[0..MAX_VSM_SIZE - 1, char] - - TFreeFn = proc (data, hint: pointer) {.noconv.} - - TContext {.final, pure.} = object - PContext* = ptr TContext - - # Socket Types - TSocket {.final, pure.} = object - PSocket* = ptr TSocket - - # Socket options. - TSockOptions* = enum - HWM = 1, - SWAP = 3, - AFFINITY = 4, - IDENTITY = 5, - SUBSCRIBE = 6, - UNSUBSCRIBE = 7, - RATE = 8, - RECOVERY_IVL = 9, - MCAST_LOOP = 10, - SNDBUF = 11, - RCVBUF = 12, - RCVMORE = 13, - FD = 14, - EVENTS = 15, - theTYPE = 16, - LINGER = 17, - RECONNECT_IVL = 18, - BACKLOG = 19, - RECOVERY_IVL_MSEC = 20, # opt. recovery time, reconcile in 3.x - RECONNECT_IVL_MAX = 21 - - # Send/recv options. - TSendRecvOptions* = enum - NOBLOCK, SNDMORE - - TPollItem*{.pure, final.} = object - socket*: PSocket - fd*: cint - events*: cshort - revents*: cshort - -# Run-time API version detection - -proc version*(major: var cint, minor: var cint, patch: var cint){.cdecl, - importc: "zmq_version", dynlib: zmqdll.} -#**************************************************************************** -# 0MQ errors. -#**************************************************************************** - -# This function retrieves the errno as it is known to 0MQ library. The goal -# of this function is to make the code 100% portable, including where 0MQ -# compiled with certain CRT library (on Windows) is linked to an -# application that uses different CRT library. - -proc errno*(): cint{.cdecl, importc: "zmq_errno", dynlib: zmqdll.} -# Resolves system errors and 0MQ errors to human-readable string. - -proc strerror*(errnum: cint): cstring {.cdecl, importc: "zmq_strerror", - dynlib: zmqdll.} -#**************************************************************************** -# 0MQ message definition. -#**************************************************************************** - -proc msg_init*(msg: var TMsg): cint{.cdecl, importc: "zmq_msg_init", - dynlib: zmqdll.} -proc msg_init*(msg: var TMsg, size: int): cint{.cdecl, - importc: "zmq_msg_init_size", dynlib: zmqdll.} -proc msg_init*(msg: var TMsg, data: cstring, size: int, - ffn: TFreeFn, hint: pointer): cint{.cdecl, - importc: "zmq_msg_init_data", dynlib: zmqdll.} -proc msg_close*(msg: var TMsg): cint {.cdecl, importc: "zmq_msg_close", - dynlib: zmqdll.} -proc msg_move*(dest, src: var TMsg): cint{.cdecl, - importc: "zmq_msg_move", dynlib: zmqdll.} -proc msg_copy*(dest, src: var TMsg): cint{.cdecl, - importc: "zmq_msg_copy", dynlib: zmqdll.} -proc msg_data*(msg: var TMsg): cstring {.cdecl, importc: "zmq_msg_data", - dynlib: zmqdll.} -proc msg_size*(msg: var TMsg): int {.cdecl, importc: "zmq_msg_size", - dynlib: zmqdll.} - -#**************************************************************************** -# 0MQ infrastructure (a.k.a. context) initialisation & termination. -#**************************************************************************** - -proc init*(io_threads: cint): PContext {.cdecl, importc: "zmq_init", - dynlib: zmqdll.} -proc term*(context: PContext): cint {.cdecl, importc: "zmq_term", - dynlib: zmqdll.} -#**************************************************************************** -# 0MQ socket definition. -#**************************************************************************** - -proc socket*(context: PContext, theType: cint): PSocket {.cdecl, - importc: "zmq_socket", dynlib: zmqdll.} -proc close*(s: PSocket): cint{.cdecl, importc: "zmq_close", dynlib: zmqdll.} -proc setsockopt*(s: PSocket, option: cint, optval: pointer, - optvallen: int): cint {.cdecl, importc: "zmq_setsockopt", - dynlib: zmqdll.} -proc getsockopt*(s: PSocket, option: cint, optval: pointer, - optvallen: ptr int): cint{.cdecl, - importc: "zmq_getsockopt", dynlib: zmqdll.} -proc bindAddr*(s: PSocket, address: cstring): cint{.cdecl, importc: "zmq_bind", - dynlib: zmqdll.} -proc connect*(s: PSocket, address: cstring): cint{.cdecl, - importc: "zmq_connect", dynlib: zmqdll.} -proc send*(s: PSocket, msg: var TMsg, flags: cint): cint{.cdecl, - importc: "zmq_send", dynlib: zmqdll.} -proc recv*(s: PSocket, msg: var TMsg, flags: cint): cint{.cdecl, - importc: "zmq_recv", dynlib: zmqdll.} -#**************************************************************************** -# I/O multiplexing. -#**************************************************************************** - -proc poll*(items: ptr TPollItem, nitems: cint, timeout: int): cint{. - cdecl, importc: "zmq_poll", dynlib: zmqdll.} - -#**************************************************************************** -# Built-in devices -#**************************************************************************** - -proc device*(device: cint, insocket, outsocket: PSocket): cint{. - cdecl, importc: "zmq_device", dynlib: zmqdll.} - -type - EZmq* = object of ESynch ## exception that is raised if something fails - TConnection* {.pure, final.} = object ## a connection - c*: PContext ## the embedded context - s*: PSocket ## the embedded socket - - TConnectionMode* = enum ## connection mode - conPAIR = 0, - conPUB = 1, - conSUB = 2, - conREQ = 3, - conREP = 4, - conDEALER = 5, - conROUTER = 6, - conPULL = 7, - conPUSH = 8, - conXPUB = 9, - conXSUB = 10 - -proc zmqError*() {.noinline, noreturn.} = - ## raises EZmq with error message from `zmq.strerror`. - var e: ref EZmq - new(e) - e.msg = $strerror(errno()) - raise e - -proc open*(address: string, server: bool, mode: TConnectionMode = conDEALER, - numthreads = 4): TConnection = - ## opens a new connection. If `server` is true, it uses `bindAddr` for the - ## underlying socket, otherwise it opens the socket with `connect`. - result.c = init(cint(numthreads)) - if result.c == nil: zmqError() - result.s = socket(result.c, cint(ord(mode))) - if result.s == nil: zmqError() - if server: - if bindAddr(result.s, address) != 0'i32: zmqError() - else: - if connect(result.s, address) != 0'i32: zmqError() - -proc close*(c: TConnection) = - ## closes the connection. - if close(c.s) != 0'i32: zmqError() - if term(c.c) != 0'i32: zmqError() - -proc send*(c: TConnection, msg: string) = - ## sends a message over the connection. - var m: TMsg - if msg_init(m, msg.len) != 0'i32: zmqError() - copyMem(msg_data(m), cstring(msg), msg.len) - if send(c.s, m, 0'i32) != 0'i32: zmqError() - discard msg_close(m) - -proc receive*(c: TConnection): string = - ## receives a message from a connection. - var m: TMsg - if msg_init(m) != 0'i32: zmqError() - if recv(c.s, m, 0'i32) != 0'i32: zmqError() - result = newString(msg_size(m)) - copyMem(addr(result[0]), msg_data(m), result.len) - discard msg_close(m) |