# HG changeset patch # User Michael Pavone # Date 1439703933 25200 # Node ID 93c28eee141e0f35e3024c6e69b54c1a3f600aa3 # Parent d61b1f0e1936af29aa8d0f76ff47e00990069883# Parent 0673ccbc737954179539b4cc4eb38dde4e15641a Merge diff -r 0673ccbc7379 -r 93c28eee141e .hgignore --- a/.hgignore Sun Aug 09 20:00:08 2015 -0700 +++ b/.hgignore Sat Aug 15 22:45:33 2015 -0700 @@ -1,3 +1,7 @@ syntax: glob *.tp.c + +syntax: regexp +^samples/[^.]*$ +^modules/[^.]*$ diff -r 0673ccbc7379 -r 93c28eee141e cbackend.js --- a/cbackend.js Sun Aug 09 20:00:08 2015 -0700 +++ b/cbackend.js Sat Aug 15 22:45:33 2015 -0700 @@ -127,6 +127,11 @@ symbols = symbols.parent; info = symbols.find(name, false, true); } + if (info && info.type == 'parent') { + //parent reference are not currently supported in the LL dialect + //but parent might refer to a module + info = toplevel.find(name); + } if (!info) { return this.cSafeName(); } @@ -405,6 +410,8 @@ throw new Error('while:do not allowed in expression context in llMessage block'); case 'addr_of': return '(&(' + args[0].toCLLExpr(vars) + '))'; + case 'struct': + return 'struct ' + args[0].toCTypeName(); case 'sizeof': return 'sizeof(' + args[0].toCTypeName() + ')'; case 'get': diff -r 0673ccbc7379 -r 93c28eee141e modules/array.tp --- a/modules/array.tp Sun Aug 09 20:00:08 2015 -0700 +++ b/modules/array.tp Sat Aug 15 22:45:33 2015 -0700 @@ -81,6 +81,23 @@ } self } + + llMessage: reverse withVars: { + front <- int32_t + back <- int32_t + tmpo <- object ptr + } andCode: { + front <- 0 + back <- size + while: { front < back } do: { + tmpo <- data get: front + data set: front (data get: back) + data set: back tmpo + front <- front + 1 + back <- back - 1 + } + self + } llMessage: length withVars: { intret <- obj_int32 ptr diff -r 0673ccbc7379 -r 93c28eee141e modules/epoll.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/epoll.tp Sat Aug 15 22:45:33 2015 -0700 @@ -0,0 +1,159 @@ +{ + _helper <- #{ + includeSystemHeader: "sys/epoll.h" + llMessage: create withVars: { + efd <- obj_int32 ptr + } andCode: { + efd <- make_object: (addr_of: obj_int32_meta) NULL 0 + efd num!: (epoll_create: 8) + efd + } + + llMessage: ctl withVars: { + oepfd <- object ptr + epfd <- obj_int32 ptr + oop <- object ptr + op <- obj_int32 ptr + ofd <- object ptr + fd <- obj_int32 ptr + omask <- object ptr + mask <- obj_uint32 ptr + data <- object ptr + res <- obj_int32 ptr + event <- struct: epoll_event + } andCode: :oepfd oop ofd omask data { + epfd <- (mcall: int32 1 oepfd) castTo: (obj_int32 ptr) + op <- (mcall: int32 1 oop) castTo: (obj_int32 ptr) + fd <- (mcall: int32 1 ofd) castTo: (obj_int32 ptr) + mask <- (mcall: int32 1 omask) castTo: (obj_int32 ptr) + res <- make_object: (addr_of: obj_int32_meta) NULL 0 + event events!: (mask num) + (addr_of: (event data)) ptr!: (data) + res num!: (epoll_ctl: (epfd num) (op num) (fd num) (addr_of: event)) + res + } + } + _constant <- macro: :name cname { + quote: (llMessage: name withVars: { + uintret <- obj_uint32 ptr + } andCode: { + uintret <- make_object: (addr_of: obj_uint32_meta) NULL 0 + uintret num!: cname + uintret + }) + } + _controlOps <- #{ + _constant: add EPOLL_CTL_ADD + _constant: mod EPOLL_CTL_MOD + _constant: del EPOLL_CTL_DEL + } + _events <- #{ + _constant: in EPOLLIN + _constant: out EPOLLOUT + _constant: rdhup EPOLLRDHUP + _constant: pri EPOLLPRI + _constant: err EPOLLERR + _constant: hup EPOLLHUP + _constant: et EPOLLET + _constant: oneshot EPOLLONESHOT + } + #{ + events <- { _events } + create <- { + efd <- _helper create + if: efd >= 0 { + _pinData <- dict hash + eobj <- #{ + llProperty: _fd withType: int32_t + llMessage: _set_fd withVars: { + ofd <- object ptr + ifd <- obj_int32 ptr + } andCode: :ofd { + ifd <- (mcall: int32 1 ofd) castTo: (obj_int32 ptr) + _fd <- ifd num + self + } + llMessage: fd withVars: { + ifd <- obj_int32 ptr + } andCode: { + ifd <- make_object: (addr_of: obj_int32_meta) NULL 0 + ifd num!: _fd + ifd + } + + addFD:withMask:data <- :nfd :mask :data { + if: (_helper ctl: fd (_controlOps add) nfd mask data) = 0 { + _pinData set: nfd data + true + } + } + deleteFD <- :dfd { + if: (_helper ctl: fd (_controlOps del) dfd 0u32 false) = 0 { + //HACK: replace data with false since we don't have a delete method on hashes yet + _pinData set: dfd false + true + } + } + modifyFD:setMask:data <- :mfd :mask :data { + if: (_helper ctl: fd (_controlOps mod) mfd mask data) = 0 { + _pinData set: mfd data + true + } + } + + event:data <- :_event:_data { + #{ + event <- { _event } + data <- { _data } + } + } + + llMessage: wait:maxEvents withVars: { + otimeout <- object ptr + omaxevents <- object ptr + timeout <- obj_int32 ptr + maxevents <- obj_int32 ptr + events <- (struct: epoll_event) ptr + retarr <- array ptr + res <- obj_int32 ptr + omask <- obj_uint32 ptr + i <- int32_t + } andCode: :otimeout omaxevents { + timeout <- (mcall: int32 1 otimeout) castTo: (obj_int32 ptr) + maxevents <- (mcall: int32 1 omaxevents) castTo: (obj_int32 ptr) + events <- GC_MALLOC_ATOMIC: (sizeof: (struct: epoll_event)) * (maxevents num) + res <- make_object: (addr_of: obj_int32_meta) NULL 0 + res num!: (epoll_wait: _fd events (maxevents num) (timeout num)) + if: (res num) >= 0 { + retarr <- make_array: 0 + mcall: resize 2 retarr res + i <- 0 + while: { i < (res num) } do: { + omask <- make_object: (addr_of: obj_uint32_meta) NULL 0 + omask num!: ((addr_of: (events get: i)) events) + mcall: append 2 retarr (mcall: event:data 3 self omask ((addr_of: ((addr_of: (events get: i)) data) ) ptr)) + i <- i + 1 + } + mcall: value 2 option retarr + } else: { + mcall: none 1 option + } + } + + llMessage: close withVars: { + } andCode: { + if: (close: _fd) = 0 { + true + } else: { + false + } + } + } + eobj _set_fd: efd + option value: eobj + } else: { + option none + } + } + } +} \ No newline at end of file diff -r 0673ccbc7379 -r 93c28eee141e modules/socket.tp --- a/modules/socket.tp Sun Aug 09 20:00:08 2015 -0700 +++ b/modules/socket.tp Sat Aug 15 22:45:33 2015 -0700 @@ -41,9 +41,8 @@ fd num!: (socket: (domain num) (type num) (protocol num)) fd } - - new <- :domain type protocol { - sfd <- socket: domain type protocol + + _sock_obj <- :sfd { #{ fd <- {sfd} @@ -113,6 +112,41 @@ } } } + + _accept_sock <- :domain type protocol { + sfd <- socket: domain type protocol + #{ + fd <- {sfd} + + llMessage: close withVars: { + sfd <- obj_int32 ptr + } andCode: { + sfd <- mcall: fd 1 self + close: (sfd num) + self + } + + llMessage: accept withVars: { + sfd <- obj_int32 ptr + newfd <- obj_int32 ptr + } andCode: { + sfd <- mcall: fd 1 self + newfd <- make_object: (addr_of: obj_int32_meta) NULL 0 + //TODO: expose peer address + newfd num!: (accept: (sfd num) NULL NULL) + if: (newfd num) >= 0 { + mcall: value 2 option (mcall: _sock_obj 2 socket newfd) + } else: { + mcall: none 1 option + } + } + } + } + + new <- :domain type protocol { + sfd <- socket: domain type protocol + _sock_obj: sfd + } llMessage: _connectTo:onPort withVars: { host <- string ptr @@ -145,12 +179,78 @@ freeaddrinfo: info sock } + connectTo:onPort <- :host :port { _connectTo: host onPort: (string: port) } - listenOn <- :port { + llMessage: listenAt:onPort withVars: { + ohost <- object ptr + host <- string ptr + oport <- object ptr + port <- string ptr + hints <- struct: addrinfo + info <- (struct: addrinfo) ptr + curinfo <- (struct: addrinfo) ptr + domain <- obj_int32 ptr + type <- obj_int32 ptr + protocol <- obj_int32 ptr + sock <- object ptr + sfd <- obj_int32 ptr + result <- int32_t + hstr <- uint8_t ptr + } andCode: :ohost :oport { + host <- (mcall: string 1 ohost) castTo: (string ptr) + port <- (mcall: string 1 oport) castTo: (string ptr) + memset: (addr_of: hints) 0 (sizeof: hints) + hints ai_family!: AF_UNSPEC + hints ai_socktype!: SOCK_STREAM + hints ai_flags!: AI_PASSIVE + hints ai_protocol!: 0 + hints ai_canonname!: NULL + hints ai_addr!: NULL + hints ai_next!: NULL + result <- getaddrinfo + if: (host bytes) = 0 { + hstr <- NULL + } else: { + hstr <- host data + } + result <- getaddrinfo: hstr (port data) (addr_of: hints) (addr_of: info) + if: result = 0 { + curinfo <- info + domain <- make_object: (addr_of: obj_int32_meta) NULL 0 + type <- make_object: (addr_of: obj_int32_meta) NULL 0 + protocol <- make_object: (addr_of: obj_int32_meta) NULL 0 + while: { curinfo != NULL } do: { + domain num!: (curinfo ai_family) + type num!: (curinfo ai_socktype) + protocol num!: (curinfo ai_protocol) + sock <- mcall: _accept_sock 4 self domain type protocol + sfd <- (mcall: fd 1 sock) castTo: (obj_int32 ptr) + if: (sfd num) != -1 { + result <- bind: (sfd num) (curinfo ai_addr) (curinfo ai_addrlen) + if: result = 0 { + curinfo <- NULL + } else: { + //failed to bind, close this socket so we can try again + close: (sfd num) + sock <- NULL + } + } + } + if: sock { + listen: (sfd num) 8 + mcall: value 2 option sock + } else: { + mcall: none 1 option + } + } else: { + mcall: none 1 option + } } - listenAt:onPort <- :host :port { + + listenOnPort <- :port { + listenAt: "" onPort: port } } diff -r 0673ccbc7379 -r 93c28eee141e modules/ui.tp --- a/modules/ui.tp Sun Aug 09 20:00:08 2015 -0700 +++ b/modules/ui.tp Sat Aug 15 22:45:33 2015 -0700 @@ -232,6 +232,7 @@ if: (_checkInitSDL: ) { _wind <- sdl createWindow: title pos: x y size: width height flags: 0u32 _wind value: :window { + _visibleWindows <- self | _visibleWindows _renderer <- window createRenderer: -1 flags: ((window renderOpts) accelerated) layout: draw: @@ -407,7 +408,12 @@ _handlers ifget: (event type) :handler { handler: event } else: { - print: "Unhandled event type: " . (event type) . "\n" + + if: (event type) = ((sdl eventTypes) mouseMotion) { + print: "Window ID: " . (event windowID) . ", x: " . (event x) . ", y: " . (event y) . "\n" + } else: { + print: "Unhandled event type: " . (event type) . "\n" + } } } none: {} } diff -r 0673ccbc7379 -r 93c28eee141e samples/echo.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/echo.tp Sat Aug 15 22:45:33 2015 -0700 @@ -0,0 +1,33 @@ +#{ + echo <- :sock { + print: "New connection\n" + data <- sock recv: 4096 + while: { (data length) > 0 } do: { + sock send: data + data <- sock recv: 4096 + } + print: "Connection closed\n" + } + + main <- :args { + port <- "2323" + if: (args length) > 1 { + port <- args get: 1 + } + (socket listenOnPort: port) value: :lsock { + print: "Listening on port " . port . "\n" + continue? <- true + while: { continue? } do: { + (lsock accept) value: :csock { + echo: csock + } none: { + print: "Failed to accept new connection\n" + continue? <- false + } + } + } none: { + print: "Failed to listen on port " . port . "\n" + } + + } +} \ No newline at end of file diff -r 0673ccbc7379 -r 93c28eee141e samples/epoll.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/epoll.tp Sat Aug 15 22:45:33 2015 -0700 @@ -0,0 +1,84 @@ +#{ + echo <- :sock { + print: "New connection\n" + data <- sock recv: 4096 + while: { (data length) > 0 } do: { + sock send: data + data <- sock recv: 4096 + } + print: "Connection closed\n" + } + continue? <- true + acceptHandler <- :sock ep { + epe <- epoll events + :_ { + (sock accept) value: :csock { + ep addFD: (csock fd) withMask: (epe in) data: (clientHandler: csock ep) + } none: { + print: "Failed to accept new connection\n" + } + } + } + + clientHandler <- :sock ep { + epe <- epoll events + _buffers <- #[] + waitingOut <- false + _me <- :eventMask { + if: eventMask and (epe in) != 0 { + _buffers append: (sock recv: 4096) + } + if: eventMask and (epe out) != 0 && (_buffers length) > 0 { + buf <- _buffers join: "" + _buffers <- #[] + sent <- sock send: buf + if: sent < (buf byte_length) { + _buffers append: (buf from: sent) + } + } + if: (_buffers length) > 0 { + if: (not: waitingOut) { + waitingOut <- true + ep modifyFD: (sock fd) setMask: (epe in) or (epe out) data: _me + } + } else: { + if: waitingOut { + waitingOut <- false + ep modifyFD: (sock fd) setMask: (epe in) data: _me + } + } + //TODO: Handle connection close/error + } + _me + } + + main <- :args { + port <- "2323" + if: (args length) > 1 { + port <- args get: 1 + } + (socket listenOnPort: port) value: :lsock { + print: "Listening on port " . port . "\n" + + epe <- epoll events + (epoll create) value: :ep { + ep addFD: (lsock fd) withMask: (epe in) data: (acceptHandler: lsock ep) + while: { continue? } do: { + (ep wait: -1 maxEvents: 16) value: :events { + foreach: events :idx ev { + handler <- ev data + handler: (ev event) + } + } none: { + print: "Failed to wait for events\n" + continue? <- false + } + } + } none: { + print: "Failed to create epoll file descriptor" + } + } none: { + print: "Failed to listen on port " . port . "\n" + } + } +} \ No newline at end of file